---
title: "Upload media or NFC data"
slug: "v1sessionsidmedia-3"
description: "Upload images for Veriff sessions with specific formats and size limits. Ensure correct context and avoid conflicts post-submission."
updated: 2026-04-24T06:25:14Z
published: 2026-04-24T06:25:14Z
---

> ## Documentation Index
> Fetch the complete documentation index at: https://devdocs.veriff.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Upload media or NFC data

Post/v1/sessions/{id}/media

### Uploads an image file or collected NFC data for a specific session ID

#### When to use this endpoint

- Use this endpoint to programmatically upload images to a verification session when
using the API-based integration (not SDK)
- Use this endpoint to upload previously collected NFC data for sessions where epassport has been used
- If using the Veriff SDK, media upload is handled automatically
within the SDK flow and this endpoint is not needed.

Common scenarios include:

- Uploading document photos captured via your own interface
- Submitting selfie images for face verification
- Providing proof of address document images
- Uploading generic documents for verification
- Uploading collected NFC data for session verification

#### Request body content

##### Image upload

- The image file is defined as base64 encoded image string inside a JSON body object
- To avoid issues with upload, keep the file smaller than:
  - Image files: 24MB in base64 encoding (approx 17MB in image files format)
  - PDFs: 20 MB in pdf format
  - Make sure the longer side of the uploaded image is max 1920px

The request must include an `image` object containing:

- `context`: what type of image is being uploaded (e.g., `document-front`, `document-back`, `face`).
See [Context types](https://veriff-dev-documentation.document360.io/docs/context-types-image-video-1) article for more info.
- `content`: base64-encoded image data with data URI scheme
- `timestamp`: when the image was captured (optional)

Supported image formats:

- .jpg
- .jpeg
- .png
- .heif
- .heic
- .webp
- .pdf

##### NFC data upload

- The NFC data object must contain `com`, `sod`, `dg1` and `dg2` data as
base64-encoded strings in the request body.

#### Response data

- Successful uploads return metadata about the uploaded media including:
  - Unique media ID for reference
  - Media type and context
  - File size and `mimetype` (format of the media file, see [here](https://devdocs.veriff.com/docs/media-file-mimetypes) for more info)
  - Download URL for accessing the uploaded image
  - `sessionId` the media belongs to
- The `timestamp` field in the response is deprecated and always returns `null`.

#### Implementation notes

- Only one image/data file can be uploaded with one request
- Make sure that you upload all the images/NFC data before setting the status to "submitted"
using the PATCH /sessions/ endpoint. If you try to upload media/data after
you have submitted the session, you may encounter the `409 - conflict` error.
- For image uploads:
  - the same context can be uploaded multiple times (e.g., for retries)
  - base64 content should include the data URI scheme prefix (e.g., `data:image/jpeg;base64,`)
  - Maximum file size limits may apply depending on integration configuration
- This endpoint requires session-level [HMAC signature](https://devdocs.veriff.com/docs/hmac-authentication-and-endpoint-security#public-api-v1) authentication
- Always ensure that you use the correct API URL to send requests. See the [API URL section](https://devdocs.veriff.com/apidocs/veriff-public-api-guides#api-url) for more info.
- The order of parameters in the real API response can differ from the order you see in this documentation. This is expected and part of the [Backwards compatible changes](https://devdocs.veriff.com/apidocs/veriff-public-api-guides#backwards-compatible-changes) requirements.

#### Additional info

##### Improved fraud detection (image uploads)

- Veriff strongly recommends you upload several images per `context`
(e.g. `face`, `document-front`, `document-back`), to indicate liveness and improve fraud detection
- Each image must be uploaded using a separate request

##### PDF support is not enabled by default (image uploads)

- Veriff supports PDF file uploads for Identity and Document Verification
(IDV) documents and Proof of Address (PoA) documents
- Contact your Solutions Engineer before starting to upload PDF files

##### Identity and Document Verification feature (image uploads)

- In [IDV](https://devdocs.veriff.com/docs/document-only-idv), document images can be uploaded in following configurations:
  - Two PDF files, where one file contains document front image and the other file contains document back image
  - Single PDF file, which has both document sides on different pages
  - Single PDF file, which has both document sides on single page
  - Veriff processes first 5 pages of uploaded PDF file. System removes empty pages from the PDF.

##### Proof of Address Verification (image uploads)

- The file that is uploaded for [Proof of Address](https://devdocs.veriff.com/docs/proof-of-address-verification) flow must contain
only one PoA document
- Max document size is 20MB

Header parametersX-AUTH-CLIENTstringRequired

Your integration's API key (occasionally referred to as the "Token", "API public key" or "Publishable key"). Required for all API requests.

You can find your API key in the Veriff Customer Portal > Settings > API keys.

Exampleyour-api-key
X-HMAC-SIGNATUREstringRequired

Request body signed with the shared secret key. Required to authenticate the request sender.

Examplea1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6q7r8s9t0u1v2w3x4y5z6
Content-TypestringRequired

Content type of the request body

Valid values[
  "application/json"
]Exampleapplication/json

Path parametersidstring (uuid) Required

Verification session ID.

Examplef04bdb47-d3be-4b28-b028-a652feb060b5

Body parameters<select class='api-response-data' aria-label='Media type'><option value='944951e6-c741-4256-aedb-366fd910a1e4'>application/json</option>
</select><select class='select-example' aria-label='Media type'><option value='af5863cc-fb68-4ffe-893a-8ce94e7db562'>media_document_front</option>
<option value='2ddf4383-c78a-41cf-8920-9cdc458a2036'>media_document_back</option>
<option value='e635cd3a-9410-46f1-887b-b8ba5087a7c7'>media_selfie_face</option>
<option value='37331f29-c6bc-4de1-9663-1c77c4d0c35a'>media_proof_of_address</option>
<option value='4f24358e-433f-4005-97a8-11d74555667e'>media_without_timestamp</option>
<option value='2566aaaa-f505-46fe-ada4-61355953e97f'>nfcDocuments_data_upload</option>
</select>media_document_front

Standard document front side upload with base64-encoded JPEG image

```json
{
  "image": {
    "context": "document-front",
    "content": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/AAAA",
    "timestamp": "2025-01-01T10:00:00Z"
  }
}
```

media_document_back

Document back side upload with base64-encoded PNG format

```json
{
  "image": {
    "context": "document-back",
    "content": "data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAAAEAAAABCAYAAAAfFcSJAAAADUlEQVR42mNk+M9QDwADhgGAWjR9awAAAABJRU5ErkJggg==",
    "timestamp": "2025-01-01T10:00:15Z"
  }
}
```

media_selfie_face

Face verification selfie upload, base64-encoded JPEG file

```json
{
  "image": {
    "context": "face",
    "content": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/AAAA",
    "timestamp": "2025-01-01T10:01:00Z"
  }
}
```

media_proof_of_address

Proof of address document upload (utility bill, bank statement, etc.), base64-encoded JPEG file

```json
{
  "image": {
    "context": "address-front",
    "content": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/AAAA",
    "timestamp": "2025-01-01T10:05:00Z"
  }
}
```

media_without_timestamp

Media upload without optional timestamp field

```json
{
  "image": {
    "context": "document-front",
    "content": "data:image/jpeg;base64,/9j/4AAQSkZJRgABAQEAYABgAAD/2wBDAAgGBgcGBQgHBwcJCQgKDBQNDAsLDBkSEw8UHRofHh0aHBwgJC4nICIsIxwcKDcpLDAxNDQ0Hyc5PTgyPC4zNDL/2wBDAQkJCQwLDBgNDRgyIRwhMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjIyMjL/wAARCAABAAEDASIAAhEBAxEB/8QAFQABAQAAAAAAAAAAAAAAAAAAAAv/xAAUEAEAAAAAAAAAAAAAAAAAAAAA/8QAFQEBAQAAAAAAAAAAAAAAAAAAAAX/xAAUEQEAAAAAAAAAAAAAAAAAAAAA/9oADAMBAAIRAxEAPwA/AAAA"
  }
}
```

nfcDocuments_data_upload

NFC data upload with base64-encoded strings for `com`, `sod`, `dg1` and `dg2` fields

```json
{
  "nfcDocuments": {
    "com": "SGVsbG8sIHRoaXMgaXMgY29tIGRhdGEgZm9yIE5GQyB1cGxvYWQu...",
    "sod": "VGhpcyBpc24ndCBhIHJlYWwgbmZjIHN0cmluZyBidXQgcmF0aGVyIGEgc2ltdWxhdGlvbi4=...",
    "dg1": "RGF0YSBmb3IgZGcxIGZpZWxkIGluIEVQYXNz...",
    "dg2": "dRGF0YSBmb3IgZGcyIGZpZWxkIGluIEVQYXNz..."
  }
}
```

Expand AllOneOfMediaUploadRequestobject (MediaUploadRequest)imageobject (MediaUploadImage)  contextstring    Required

Context of the uploaded media, i.e., what the uploaded image was taken of.

Veriff captures multiple images, therefore the image with the `-pre` suffix is the first one, and the one without is the second image.

See [Context types](https://veriff-dev-documentation.document360.io/docs/context-types-image-video-1) article for more info.

Exampledocument-front
contentstring  (base64)    Required

The media file to be uploaded, as base64 encoded image (.jpg, .jpeg, .png, .heif, .heic, .webp and .pdf formats are supported).

Exampledata:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAA+.../9fgAEAKcxisFjVfn0AAAAASUVORK5CYII=
timestampstring  (date-time)    

Timestamp of the upload as combined ISO 8601 date and time in UTC.

Format: YYYY-MM-DDTHH:MM:SS.sssZ.

Example2020-01-01T12:34:56.780Z

NfcDocumentsUploadRequestobject (NfcDocumentsUploadRequest)nfcDocumentsobject (NfcDocuments)  Requiredcomstring  (base64)    Required

Base64 encoded content of the COM file retrieved from the NFC chip of the document.

COM file contains info about the version of the data structure and a list of which Data Groups (DGs) are actually available on that specific document.

ExampleSGVsbG8sIHRoaXMgaXMgY29tIGRhdGEgZm9yIE5GQyB1cGxvYWQu...
sodstring  (base64)    Required

Base64 encoded content of the SOD file retrieved from the NFC chip of the document.

SOD file contains the digital signature of the data read from the NFC chip, ensuring its authenticity and integrity.

ExampleVGhpcyBpc24ndCBhIHJlYWwgbmZjIHN0cmluZyBidXQgcmF0aGVyIGEgc2ltdWxhdGlvbi4=...
dg1string  (base64)    Required

Base64 encoded content of the DG1 file retrieved from the NFC chip of the document.

DG1 file contains info found in the physical Machine Readable Zone (MRZ) of the document, typically including the personal data of the document holder, such as name, date of birth, and document number.

ExampleRGF0YSBmb3IgZGcxIGZpZWxkIGluIEVQYXNz...
dg2string  (base64)    Required

Base64 encoded content of the DG2 file retrieved from the NFC chip of the document.

DG2 file contains the biometric data of the document holder, such as their facial image.

ExampleRGF0YSBmb3IgZGcyIGZpZWxkIGluIEVQYXNz...

Responses200

Media uploaded successfully.

HeadersContent-TypestringResponse content type.Valid values[
  "application/json"
]
X-AUTH-CLIENTstringAPI key echoed back in response.
X-HMAC-SIGNATUREstringResponse body signed with the shared secret key. Required to authenticate the response sender.
<select class='api-response-data' aria-label='Media type'><option value='01a2b21c-4fdc-4463-8a94-e4ce21d72cc5'>application/json</option>
</select><select class='select-example' aria-label='Media type'><option value='a8a513b9-889e-4a81-89b1-072b74d2d43c'>document_front_success</option>
<option value='f40803bb-76a2-479e-a643-66b686b49567'>face_upload_success</option>
<option value='a06996a9-f271-4698-84a4-d0a9df8a5ecb'>proof_of_address_success</option>
<option value='aad6a714-b419-4e0e-bfca-db1888aaf5a4'>nfc_data_upload_success</option>
</select>document_front_success

Document front uploaded successfully

```json
{
  "status": "success",
  "image": {
    "id": "d69a07cf-4434-4d36-be6c-d22af7dc01fb",
    "name": "document-front",
    "context": "document-front",
    "timestamp": null,
    "size": 245678,
    "mimetype": "image/jpeg",
    "url": "https://exampleURL.com/v1/media/d69a07cf-4434-4d36-be6c-d22af7dc01fb",
    "sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5"
  }
}
```

face_upload_success

Selfie uploaded successfully

```json
{
  "status": "success",
  "image": {
    "id": "a1b2c3d4-e5f6-4g7h-8i9j-0k1l2m3n4o5p",
    "name": "face",
    "context": "face",
    "timestamp": null,
    "size": 189234,
    "mimetype": "image/jpeg",
    "url": "https://exampleURL.com/v1/media/a1b2c3d4-e5f6-4g7h-8i9j-0k1l2m3n4o5p",
    "sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5"
  }
}
```

proof_of_address_success

Proof of Address document uploaded successfully

```json
{
  "status": "success",
  "image": {
    "id": "6q7r8s9t-0u1v-4w3x-4y5z-6a1b2c3d4e5f",
    "name": "address-front",
    "context": "address-front",
    "timestamp": null,
    "size": 512890,
    "mimetype": "image/jpeg",
    "url": "https://exampleURL.com/v1/media/6q7r8s9t-0u1v-4w3x-4y5z-6a1b2c3d4e5f",
    "sessionId": "f04bdb47-d3be-4b28-b028-a652feb060b5"
  }
}
```

nfc_data_upload_success

NFC data uploaded successfully

```json
{
  "status": "success",
  "nfcDocument": {
    "id": "908d041f-e66e-47de-9664-0950a201fd85",
    "name": "document-nfc",
    "context": "document-nfc",
    "timestamp": null,
    "size": 29584,
    "mimetype": "application/octet-stream",
    "url": "https://exampleURL.com/v1/media/908d041f-e66e-47de-9664-0950a201fd85",
    "sessionId": "86c71df5-c163-4022-9c94-1fb6dc903a98"
  }
}
```

Expand AllOneOfImageUploadResponseobject (ImageUploadResponse)statusstring    

Upload status.

Examplesuccess
imageobject (VerificationSessionImageUpload)  idstring  (uuid)    

UUID v4 which identifies the uploaded media.

Exampled69a07cf-4434-4d36-be6c-d22af7dc01fb
namestring    

Name which identifies the uploaded media.

Valid values[
  "address-front",
  "document-and-face",
  "document-and-face-pre",
  "document-back",
  "document-back-barcode",
  "document-back-barcode-pre",
  "document-back-pre",
  "document-back-qrcode",
  "document-back-qrcode-pre",
  "document-front",
  "document-front-face-cropped",
  "document-front-pre",
  "document-front-qrcode",
  "document-front-qrcode-pre",
  "face",
  "face-cropped",
  "face-nfc",
  "face-pre",
  "face-reference",
  "registry-face"
]Exampledocument-front
contextstring    

Context type of the uploaded media.

See [Context types](https://veriff-dev-documentation.document360.io/docs/context-types-image-video-1) article for more info.

Valid values[
  "address-front",
  "document-and-face",
  "document-and-face-pre",
  "document-back",
  "document-back-barcode",
  "document-back-barcode-pre",
  "document-back-pre",
  "document-back-qrcode",
  "document-back-qrcode-pre",
  "document-front",
  "document-front-face-cropped",
  "document-front-pre",
  "document-front-qrcode",
  "document-front-qrcode-pre",
  "face",
  "face-cropped",
  "face-nfc",
  "face-pre",
  "face-reference",
  "registry-face"
]Exampledocument-front
timestampstring   | null Deprecated 

Always returns `null`.

Example
sizeinteger    

Size of the uploaded media, in bytes.

Example12345
mimetypestring    

File type of the uploaded media.

See [Media file mimetypes](https://devdocs.veriff.com/docs/media-file-mimetypes) article for more info.

Valid values[
  "image/jpeg",
  "image/jpg",
  "image/png",
  "image/heif",
  "image/heic",
  "image/webp",
  "application/pdf"
]Exampleimage/jpeg
urlstring    

Download URL of the media.

Examplehttps://exmpleURL.com/v1/media/d69a07cf-4434-4d36-be6c-d22af7dc01fb
sessionIdstring    

UUID v4 of the verification session the uploaded media belongs to.

Exampled69a07cf-4434-4d36-be6c-d22af7dc01fb

NfcUploadResponseobject (NfcUploadResponse)statusstring    

Upload status.

Examplesuccess
nfcDocumentsobject (NfcDocumentsUpload)  idstring  (uuid)    

UUID v4 which identifies the uploaded NFC data.

Example89e42557-0ac6-4307-a645-3c14aedfef1f
namestring    

Name which identifies the uploaded NFC data.

Valid values[
  "document-nfc"
]Exampledocument-nfc
contextstring    

Context type of the uploaded NFC data.

Valid values[
  "document-nfc"
]Exampledocument-nfc
timestampstring   | null Deprecated 

Always returns `null`.

Example
sizeinteger    

Size of the uploaded NFC data, in bytes.

Example29584
mimetypestring    

File type of the uploaded NFC data.

Exampleapplication/octet-stream
sessionIdstring  (uuid)    

UUID v4 of the verification session the uploaded NFC data belongs to.

Example504c4d55-aa1e-47d1-a4e3-06ad0a51e564
urlstring    

Download URL of the NFC data.

Examplehttps://exampleURL.com/v1/media/89e42557-0ac6-4307-a645-3c14aedfef1f

400

Bad request

HeadersContent-TypestringResponse content type.Valid values[
  "application/json"
]
X-AUTH-CLIENTstringAPI key echoed back in response.
X-HMAC-SIGNATUREstringResponse body signed with the shared secret key. Required to authenticate the response sender.
<select class='api-response-data' aria-label='Media type'><option value='b2906f11-d8cb-481f-aeb4-9bddb51dc4f8'>application/json</option>
</select><select class='select-example' aria-label='Media type'><option value='492b7d97-298c-4366-ba91-2cab1ad80345'>bad_request</option>
<option value='2062ccef-a0da-46e6-b982-b5e58c370364'>invalid_nfc_data</option>
</select>bad_request

Request failed

```json
{
  "status": "fail",
  "code": "1101",
  "message": "Validation failed"
}
```

invalid_nfc_data

Invalid NFC format

The request is missing required data groups or the base64 format is incorrect.

```json
{
  "status": "fail",
  "code": "1410",
  "error": "NFC data format is invalid or missing required fields"
}
```

object  statusstring    Valid values[
  "fail"
]Examplefail
codestring    Example1101
messagestring    ExampleValidation failed

401

Unauthorized

HeadersContent-TypestringResponse content type.Valid values[
  "application/json"
]
X-AUTH-CLIENTstringAPI key echoed back in response.
<select class='api-response-data' aria-label='Media type'><option value='787d2fa7-6659-44e7-ba6b-b11b29635a91'>application/json</option>
</select><select class='select-example' aria-label='Media type'><option value='556b5c3a-b2f0-43fe-b9c5-01502cf448d1'>missing_api_key</option>
</select>missing_api_key

Missing API key

Request failed because x-auth-client header is missing

```json
{
  "status": "fail",
  "code": "1101",
  "message": "Mandatory X-AUTH-CLIENT header containing the API key is missing from the request."
}
```

object  statusstring    Valid values[
  "fail"
]Examplefail
codestring    Example1101
messagestring    ExampleMandatory X-AUTH-CLIENT header containing the API key is missing from the request.

404

Session not found

HeadersContent-TypestringResponse content type.Valid values[
  "application/json"
]
X-AUTH-CLIENTstringAPI key echoed back in response.
X-HMAC-SIGNATUREstringResponse body signed with the shared secret key. Required to authenticate the response sender.
<select class='api-response-data' aria-label='Media type'><option value='23b04eb0-a26c-41f6-a523-22ea8742d6b0'>application/json</option>
</select><select class='select-example' aria-label='Media type'><option value='69d00ecc-021d-4e8b-82f1-aa1844272e96'>session_not_found</option>
</select>session_not_found

Request failed because session does not exist

```json
{
  "status": "fail",
  "code": "1101",
  "message": "Resource not found"
}
```

object  statusstring    Valid values[
  "fail"
]Examplefail
codestring    Example1101
messagestring    ExampleResource not found

413

Bad request

HeadersContent-TypestringResponse content type.Valid values[
  "application/json"
]
X-AUTH-CLIENTstringAPI key echoed back in response.
X-HMAC-SIGNATUREstringResponse body signed with the shared secret key. Required to authenticate the response sender.
<select class='api-response-data' aria-label='Media type'><option value='0417003c-5b2d-4a3b-a42b-49e2fb43c9d8'>application/json</option>
</select><select class='select-example' aria-label='Media type'><option value='658c2210-3494-457c-9202-5e8e366ae013'>nfc_payload_too_large</option>
</select>nfc_payload_too_large

Payload size exceeded

The combined NFC data exceeds the 500KB limit.

```json
{
  "status": "fail",
  "code": "1412",
  "error": "NFC payload too large. Maximum size is 500KB"
}
```

object  statusstring    Valid values[
  "fail"
]Examplefail
codestring    

Veriff-specific error code for NFC failures.

Example1410
errorstring    

Detailed error message.

ExampleNFC data format is invalid or missing required fields

500

Internal server error

HeadersContent-TypestringResponse content type.Valid values[
  "application/json"
]
X-AUTH-CLIENTstringAPI key echoed back in response.
X-HMAC-SIGNATUREstringResponse body signed with the shared secret key. Required to authenticate the response sender.
<select class='api-response-data' aria-label='Media type'><option value='16ada5af-4ccd-486f-91da-839dac06cda8'>application/json</option>
</select><select class='select-example' aria-label='Media type'><option value='33de8f48-a1d6-4060-93eb-0737bc7ecfe4'>server_error</option>
</select>server_error

Internal server error

Request failed due to an internal server error

```json
{
  "status": "fail",
  "code": "1101",
  "message": "Something went wrong"
}
```

object  statusstring    Valid values[
  "fail"
]Examplefail
codestring    Example1101
messagestring    ExampleSomething went wrong

		
			

---

#### Media compression support info

This endpoint accepts compressed request bodies with `Content-Encoding: gzip` or `Content-Encoding: deflate`. Because media uploads carry base64-encoded images inside JSON, compression typically reduces payload size by 25–35%, lowering bandwidth usage and upload latency.

Request-body compression is a **transport optimization**, it does not change the signing contract. Your signature is always computed over the **uncompressed** JSON body. The server decompresses the payload before validating the signature.

No configuration changes are required for the integration to start using this feature. To use compression, include exactly one of these Content-Encoding values in your request:

- `gzip` (recommended)
- `deflate`

Combined values such as `gzip, deflate` or `deflate, gzip` are not supported. `br` is not supported on this endpoint.

**Operation order**

Getting the order right is critical. The signature must cover the **uncompressed payload**, and the compressed payload must decompress back to the exact bytes that were signed.

1. Build the JSON payload (same as today)
2. Serialize the JSON to bytes
3. Compute the signature over the serialized bytes ← sign BEFORE compressing
4. Compress the serialized bytes (`gzip` or `deflate`)
5. Send the compressed bytes with the matching Content-Encoding value

If you compress first and then sign the compressed bytes, signature validation will fail.

**Request headers**

- `x-auth-client` = your API key
- `x-hmac-signature` = Lowercase hex HMAC-SHA256 (64 chars, no prefix) of the uncompressed JSON body
- `Content-type` = application/json
- `Content-Encoding` = `gzip` (recommended) or `deflate`

**Code examples**

The examples below use `gzip`. If you use `deflate`, keep the same signing flow and set `Content-Encoding: deflate` with deflate-compressed bytes.

<meta charset="UTF-8"> <title>Python Code Example</title>

**Python**

TextText

```
import base64
import gzip
import hashlib
import hmac
import json
import requests

API_KEY = "your-api-key"
SHARED_SECRET = "your-shared-secret"
SESSION_ID = "your-session-id"
BASE_URL = "https://stationapi.veriff.com"

# Read and encode image
with open("document_front.jpg", "rb") as f:
    image_bytes = f.read()
b64_content = base64.b64encode(image_bytes).decode("utf-8")

# Step 1–2: Build and serialize the JSON payload
payload = {
    "image": {
        "context": "document-front",
        "content": f"data:image/jpeg;base64,{b64_content}",
    }
}
payload_bytes = json.dumps(payload, separators=(",", ":")).encode("utf-8")

# Step 3: Sign the UNCOMPRESSED payload
signature = hmac.new(
    SHARED_SECRET.encode("utf-8"),
    payload_bytes,
    hashlib.sha256,
).hexdigest()

# Step 4: Compress
compressed = gzip.compress(payload_bytes)

# Step 5: Send with Content-Encoding: gzip
response = requests.post(
    f"{BASE_URL}/v1/sessions/{SESSION_ID}/media",
    data=compressed,                        # raw bytes, not json=
    headers={
        "X-AUTH-CLIENT": API_KEY,
        "X-HMAC-SIGNATURE": signature,
        "Content-Type": "application/json",
        "Content-Encoding": "gzip",
    },
)
print(response.status_code, response.json())
```

<meta charset="UTF-8"> <title>Node Code Example</title>

**Node.js**

TextText

```
const crypto = require('crypto');
const fs = require('fs');
const zlib = require('zlib');
const https = require('https');

const API_KEY = 'your-api-key';
const SHARED_SECRET = 'your-shared-secret';
const SESSION_ID = 'your-session-id';
const BASE_URL = 'stationapi.veriff.com';

// Read and encode image
const imageBytes = fs.readFileSync('document_front.jpg');
const b64Content = imageBytes.toString('base64');

// Step 1–2: Build and serialize the JSON payload
const payload = {
  image: {
    context: 'document-front',
    content: `data:image/jpeg;base64,${b64Content}`,
  },
};
const payloadBytes = Buffer.from(JSON.stringify(payload));

// Step 3: Sign the UNCOMPRESSED payload
const signature = crypto
  .createHmac('sha256', SHARED_SECRET)
  .update(payloadBytes)
  .digest('hex');

// Step 4: Compress
const compressed = zlib.gzipSync(payloadBytes);

// Step 5: Send with Content-Encoding: gzip
const req = https.request(
  {
    hostname: BASE_URL,
    path: `/v1/sessions/${SESSION_ID}/media`,
    method: 'POST',
    headers: {
      'X-AUTH-CLIENT': API_KEY,
      'X-HMAC-SIGNATURE': signature,
      'Content-Type': 'application/json',
      'Content-Encoding': 'gzip',
      'Content-Length': compressed.length,
    },
  },
  (res) => {
    let body = '';
    res.on('data', (chunk) => (body += chunk));
    res.on('end', () => console.log(res.statusCode, body));
  }
);
req.write(compressed);
req.end();
```

**Common mistakes**

**Signing the compressed bytes.** The most common integration error. If you compress first and then compute the HMAC over the compressed output, the server will reject the request with a 401. Always sign the uncompressed JSON body.

**Encoding/header mismatch.** If you send `Content-Encoding: gzip` or `Content-Encoding: deflate` but the body is not encoded accordingly, the request fails with a 400. If you are not compressing, omit the `Content-Encoding` header.

**Using `json=` in your HTTP library with compressed bytes.** When sending compressed data, pass compressed bytes as a raw body (`data=` in Python requests, `content=` in httpx), not as a JSON parameter. Setting `json=` causes the HTTP library to re-serialize the payload, which defeats compression and breaks the signature.

**Double compression.** Do not set `Content-Encoding` if your HTTP client or proxy is already compressing the request transparently. If in doubt, check the outbound request body and `Content-Encoding` header.

**Using unsupported or combined encodings.** Supported values are exactly `gzip` or `deflate`. Combined values (for example, `gzip, deflate`) and other encodings (for example, `br`) fail with a 415 http error.

---

<title style="font-size: 15px;">Document Versioning</title>

**Changelog**

| Date | Description |
| --- | --- |
| Apr 24, 2026 | In intro section, context type example changed from `selfie` to `face` `timestamp` description and examples standardized to UTC Z-only format and updated |
| Mar 24, 2026 | "Media compression support info" section added |
| Mar 20, 2026 | NFC data upload info and examples added |
| Mar 9, 2026 | Documentation updated: parent categories rearranged, intro section expanded, request and response examples added |
| Nov 26, 2025 | Added the "Note about improved fraud detection" section |
| Oct 2, 2025 | `vrf-` headers removed from response headers |
| Aug 6, 2025 | Response headers added |
| May 2, 2025 | Updated the info about PDF files support for Proof of Address Verification flow to match the logic of [Proof of Address Verification](https://devdocs.veriff.com/docs/proof-of-address-verification) solution Note about multiple PDF uploads for PoA solution moved to the legacy [Proof of Address Extraction](https://devdocs.veriff.com/docs/proof-of-address-extraction) documentation as it is only applicable for that flow. |
| Apr 21, 2025 | Added a note about the max length of the longer side of an image |
| Mar 12, 2025 | Documentation published |
