Creates a verification session with the data specified in the request body
When to use this endpoint
- Use this endpoint to initiate a new verification session for an end-user. Every verification flow begins with creating a session.
Request body content
The contents of the request body depends on:
- Whether you are using the SDK or API to capture end-user data
- The type of verification solution the session is created for
Minimum request body:
- Empty
verificationobject
Payload examples:
- Click on the "Show examples" button in "Request" section to see request body examples for specific solutions/products.
Response data
Once you create the verification session, you receive:
- Unique session
id(store this - required for other endpoints) - Unique
sessionToken(legacy purposes, see FAQ) - Session URL in
verification.urlparameter (required for SDK integrations)
Getting session results
After the end-user completes the verification:
- Primary: webhook notifications sent to
webhook URL - Secondary: Poll
GET /v1/sessions/{id}/decisionendpoint - Backup: Use polling if webhook delivery fails
Implementation notes
- Store the returned session
id- it is required for all other session-related endpoints - Always ensure that you use the correct API URL to send requests. See the API URL section for more info.
- See Javascript sample implementation for SDK integration examples
- 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 requirements.
Additional info: end-user flow after session creation
- Create session → Get
session.verification.url - Redirect end-user to
verification.url - End-user completes verification flow
- End-user redirected to your callback URL (if configured)
- Receive webhook notification OR poll for results
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 under Settings > API keys.
Must be set to application/json
Session initialization data
Empty verification object - minimum required to create a session
{
"verification": {}
}Session with person data, document details, and end-user ID
{
"verification": {
"callback": "https://example.com/callback",
"person": {
"firstName": "John",
"lastName": "Smith",
"idNumber": "123456789"
},
"document": {
"number": "B01234567",
"type": "PASSPORT",
"country": "US"
},
"endUserId": "c1de400b-1877-4284-8494-071d37916197"
}
}Session with person data, document details, end-user ID, and host app link
{
"verification": {
"callback": "https://example.com/callback",
"hostAppLink": "myapp://verification/complete",
"person": {
"firstName": "John",
"lastName": "Smith",
"idNumber": "123456789"
},
"document": {
"number": "B01234567",
"type": "PASSPORT",
"country": "US"
},
"endUserId": "c1de400b-1877-4284-8494-071d37916197"
}
}Session with service coverage configuration
{
"verification": {
"serviceCoverage": {
"country": "US"
}
}
}Session with person data, document details, end-user ID, and consent array
{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith",
"idNumber": "123456789"
},
"document": {
"number": "B01234567",
"type": "PASSPORT",
"country": "US"
},
"endUserId": "c1de400b-1877-4284-8494-071d37916197",
"consents": [
{
"type": "ine",
"approved": true,
"text": "User agrees to share their INE details",
"timestamp": "2026-05-07T08:00:00Z"
}
]
}
}Session for AML/sanctions screening with required person data
{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith",
"dateOfBirth": "1990-01-01"
}
}
}Session for matching end-user's identity and biometric data against governmental biometric databases. Currently available only for Brazilian CPF Biometric Database.
{
"verification": {
"person": {
"idNumber": 12345678901,
"firstName": "João",
"lastName": "Silva",
"dateOfBirth": "1990-01-15"
},
"vendorData": 12345678,
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4"
}
}Session to validate Brazilian users against social benefit registries. See here for full documentation.
{
"verification": {
"person": {
"idNumber": 12345678901,
"dateOfBirth": "1990-01-15"
}
}
}Session to validate users against Brazil's betting exclusion registries. See here for full documentation.
{
"verification": {
"person": {
"idNumber": 12345678901,
"dateOfBirth": "1990-01-15"
}
}
}Session for Mexican CURP database verification using person ID number
{
"verification": {
"person": {
"idNumber": "VISH560427MSRLNL06"
}
}
}Session for Mexican INE database verification using CIC and IFE identifier (OCR code) for card type D
{
"verification": {
"callback": "https://yourwebsite.com/webhook",
"document": {
"number": "123456789M00000000",
"documentNumberIdentifiers": {
"mxIfe": 1234567890123
}
}
}
}Session for Mexican INE database verification using CIC and INE identifier (Identificador Ciudadano) for card types E, F, G, and H
{
"verification": {
"callback": "https://yourwebsite.com/webhook",
"document": {
"number": "123456789M00000000",
"documentNumberIdentifiers": {
"mxIne": 1234567890123
}
}
}
}Proof of Address address matching session to compare addresses from two different sources
{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith"
},
"address": {
"fullAddress": "123, Main Street, Your County, Anytown 12345"
},
"proofOfAddress": {
"acceptableTypes": [
{
"name": "UTILITY_BILL"
},
{
"name": "PHONE_BILL"
},
{
"name": "TAX_DOCUMENT"
}
]
},
"endUserId": "c1de400b-1877-4284-8494-071d37916197"
}
}Can be used for address extraction and address validation solutions. See the full Proof of Address documentation here
{
"verification": {
"proofOfAddress": {
"acceptableTypes": [
{
"name": "UTILITY_BILL"
},
{
"name": "PHONE_BILL"
},
{
"name": "TAX_DOCUMENT"
}
]
},
"endUserId": "c1de400b-1877-4284-8494-071d37916197"
}
}Can be used for address extraction and address validation solutions. See the full Proof of Address documentation here
{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith"
},
"proofOfAddress": {
"acceptableTypes": [
{
"name": "UTILITY_BILL"
},
{
"name": "PHONE_BILL"
},
{
"name": "TAX_DOCUMENT"
}
]
},
"endUserId": "c1de400b-1877-4284-8494-071d37916197"
}
}Session for Biometric Authentication to verify identity by comparing two selfie images
{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith"
},
"endUserId": "a1b2c35d-e8f7-6d5e-3cd2-a1b2c35db3d4",
"vendorData": 12345678
}
}Session with custom tag parameter
{
"verification": {
"vendorData": 12345678,
"tag": "your_custom_tag_max_64_characters"
}
}Session for UK DIATF M1B verification with full address
{
"verification": {
"address": {
"fullAddress": "123, Main Street, Your County, Anytown 12345"
}
}
}Session for US Database Verification: Light KYC verification with person details and address
{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith",
"dateOfBirth": "1990-01-01",
"phoneNumber": "8888888888"
},
"address": {
"fullAddress": "123, Main Street, Your County, Anytown 12345"
}
}
}Session for Unstructured Docs verification without initData — for document extraction only (no InitData Matching validation).
{
"verification": {}
}Session for Unstructured Docs verification with all possible initData fields.
{
"verification": {
"document": {
"number": "847293651024738569"
},
"person": {
"fullName": "JUAN MARTINEZ",
"occupation": "Driver"
},
"address": {
"fullAddress": "AV INSURGENTES SUR 2847 PISO 3 COL DEL VALLE BENITO JUAREZ CIUDAD DE MEXICO MEXICO CP 03100"
},
"endUserId": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"
}
}Session for US Database Verification: SSN check with document number and person data
{
"verification": {
"person": {
"firstName": "John",
"lastName": "Smith",
"dateOfBirth": "1990-01-01"
},
"document": {
"number": "123456789"
}
}
}Verification object
The callback URL to where the end-user is redirected after the verification session is completed.
Default is visible in the Veriff Customer Portal -> Settings. Changing the value in this request body will overwrite the default callback URL, but it will not change the callback URL that is visible in the Customer Portal.
Data about the person being verified.
Person's first name.
Person's last name.
Person's national identification number.
Person's phone number.
Person's gender.
Person's date of birth.
Format: YYYY-MM-DD.
Person's email address.
Person's marital status (mandatory only for some registry checks).
Person's deceased status (mandatory only for some registry checks).
Person's full name.
Optional. Used as initData for Unstructured Docs InitData Matching validation or in Metadata Database Verification.
Person's occupation.
Optional. Used as initData for Unstructured Docs InitData Matching validation.
Person's landline phone number.
Optional, used in some registry checks, for example Metadata Database Verification.
Person's partner's first name.
Optional, used in some registry checks, for example Metadata Database Verification.
Person's partner's last name.
Optional, used in some registry checks, for example Metadata Database Verification.
Person's marriage date. Format: YYYY-MM-DD.
Optional, used in some registry checks, for example Metadata Database Verification.
Person's middle name.
Optional, used in some registry checks, for example Metadata Database Verification.
Person's second last name (if applicable).
Optional, used in some registry checks, for example Metadata Database Verification.
Data about the document of the person being verified.
Document number, [a-zA-Z0-9] characters only.
Document issuing country, in capital letters.
Document type for Document + Selfie verification or Document-only verification
Date of the document's first issue. Format: YYYY-MM-DD.
Document type for the ID card, [a-zA-Z] characters only.
Optional, only required for Colombia identity verification.
Specific document number identifiers.
Optional, currently used only for the Official Database Verification step for INE database verification solution.
Field representing the last 9 digits of the first line of the MRZ of an INE card. Also known as "Identificador del ciudadano".
Field representing the last 13 digits of the first line of the MRZ of an IFE card. Also known as "ocr".
Document issue date or valid-from date. Format: YYYY-MM-DD.
Optional, used in some registry checks, for example Metadata Database Verification.
Document expiry date. Format: YYYY-MM-DD.
Optional, used in some registry checks, for example Metadata Database Verification.
The version or revision number of the document.
Optional, used in some registry checks, for example Metadata Database Verification.
The specific type or category of the document.
Optional, used in some registry checks, for example Metadata Database Verification.
The document's unique identification number.
Optional, used in some registry checks, for example Metadata Database Verification.
The state or region where the document was issued.
Optional, used in some registry checks, for example Metadata Database Verification.
The reference number of the document.
Optional, used in some registry checks, for example Metadata Database Verification.
A registration identifier assigned to the document by the issuing authority.
Optional, used in some registry checks, for example Metadata Database Verification.
Data about the address of the person being verified.
Full address.
Street name.
Optional, used in some registry checks, for example Metadata Database Verification.
House number.
Optional, used in some registry checks, for example Metadata Database Verification.
Postal code.
Optional, used in some registry checks, for example Metadata Database Verification.
Any human settlement, including cities, towns, villages, hamlets, localities, etc.
Optional, used in some registry checks, for example Metadata Database Verification.
Any administrative division, such as a state, province, or region.
Optional, used in some registry checks, for example Metadata Database Verification.
Apartment, suite, or unit number.
Optional, used in some registry checks, for example Metadata Database Verification.
Usually an unofficial neighbourhood name like "Harlem", "South Bronx", or "Crown Heights".
Optional, used in some registry checks, for example Metadata Database Verification.
Data about the PoA document of the person being verified.
Optional, should be only used in Proof of Address integrations.
Accepted types for proof of address document.
This parameter should be sent only when using the proof of address solution and after the Acceptable document types feature has been configured for your integration.
Name of the accepted proof of address document type.
Object for specifying which country's verification services should be offered to the end-user.
ISO 3166-1 alpha-2 country code indicating which country's verification services should be offered to the end user. Not available by default.
The unique identifier that you created for your end-user. It can be max 1,000 characters long and contain only non-semantic data that can not be resolved or used outside your systems or environments.
Veriff returns it unmodified in webhooks and API response payloads, or as
null if not provided.
The UUID that you created for your end-user, that can not be
resolved or used outside your systems or environments.
Veriff returns it unmodified in webhooks and API response payloads, or as null if
not provided.
Array of objects listing the type of consent given.
Optional, should be only included for solutions/products that require consent (e.g., MX INE Biometric Database or Metadata Database Verification).
Indicates the feature for which the consent is given.
Mandatory field for MX INE Biometric Database Verification and some registries in Metadata Database Verification.
If true, indicates that the consent has been given.
MX INE Biometric Database Verification requires that approved=true is sent. If false or missing,
the session is not created.
A mandatory field for some registries in Metadata Database Verification.
Consent text exactly (same language) as shown to the end-user.
Mandatory when type=eid and approved=true. Optional in all other cases.
Timestamp recording when the consent was given by the end-user, as combined ISO 8601 date and time in UTC. Always optional.
Format: YYYY-MM-DDTHH:MM:SS.sssZ.
Custom marker for the session that you create, max length 64 characters. Can be sent only if enabled for your integration.
Contact your Solutions Engineer or Veriff Customer Support for info and configuration.
Optional link used to return the end-user to the host application during an external provider flow, which typically takes place in a browser. Send this field only if you have built your integration to return the end-user to the host app.
Created session
API request status.
Verification object.
Verification session status.
UUID v4 which identifies the verification session.
URL of the verification session. The end-user is redirected here to
go through the flow. It is a combination of the baseUrl and the
sessionToken.
Session-specific token of the verification.
The base url the sessionToken can be used for.
The UUID that you created for your end-user, that can not be
resolved or used outside your systems or environments.
Veriff returns it unmodified in webhooks and API response payloads, or as null if
not provided.
The unique identifier that you created for your end-user. It can be
max 1,000 characters long and contain only non-semantic data that can
not be resolved or used outside your systems or environments.
Veriff returns it unmodified in webhooks and API response payloads, or as
null if not provided.
Bad request
Unauthorized
Too many requests
Internal server error
Payload compression support info
This endpoint accepts compressed request bodies with Content-Encoding: gzip or Content-Encoding: deflate. Note that this endpoint accepts a plain JSON payload, so compression is not always necessary. For typical session initialization payloads, the bandwidth savings are negligible and the extra CPU cost on the client side outweighs the benefit.
Where compression genuinely helps is when the request includes consent records that carry a text field. The consent text typically contains the full, human-readable consent statement that was shown to the end user, and can be several KB or larger (especially for legal or regulatory consents). In those cases, gzip or deflate can shrink the payload by 60–80%, which is worthwhile.
As a rule of thumb:
- If your payload is just a verification block with no
consents, or withconsentsthat omit thetextfield, sending it uncompressed is fine. - If you include one or more consent objects with a non-trivial
textfield, prefer compression.
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.
- Build the JSON payload
- Serialize the JSON to bytes
- Compute the signature over the serialized bytes ← sign BEFORE compressing
- Compress the serialized bytes (
gzipordeflate) - 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 keyx-hmac-signature= Lowercase hex HMAC-SHA256 (64 chars, no prefix) of the uncompressed JSON bodyContent-type= application/jsonContent-Encoding=gzip(recommended) ordeflate
Code examples
The examples below use gzip and include a consent with a long text field, which is the case where compression actually pays off. If you use deflate, keep the same signing flow and set Content-Encoding: deflate with deflate-compressed bytes.
Python
import gzip
import hashlib
import hmac
import json
import requests
API_KEY = "your-api-key"
SHARED_SECRET = "your-shared-secret"
BASE_URL = "https://stationapi.veriff.com"
# A realistic consent text is typically much longer than this snippet.
CONSENT_TEXT = (
"I consent to Veriff processing my personal data, including biometric data, "
"for identity verification purposes in accordance with the Privacy Notice. "
# ... full legal text continues, often several KB ...
)
# Step 1–2: Build and serialize the JSON payload
payload = {
"verification": {
"callback": "https://example.com/callback",
"vendorData": "customer-123",
"consents": [
{
"type": "general",
"approved": True,
"text": CONSENT_TEXT,
"timestamp": "2026-05-08T10:00:00Z",
}
],
}
}
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",
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())Node.js
const crypto = require('crypto');
const zlib = require('zlib');
const https = require('https');
const API_KEY = 'your-api-key';
const SHARED_SECRET = 'your-shared-secret';
const BASE_URL = 'stationapi.veriff.com';
// A realistic consent text is typically much longer than this snippet.
const CONSENT_TEXT =
'I consent to Veriff processing my personal data, including biometric data, ' +
'for identity verification purposes in accordance with the Privacy Notice. ' +
// ... full legal text continues, often several KB ...
'';
// Step 1–2: Build and serialize the JSON payload
const payload = {
verification: {
callback: 'https://example.com/callback',
vendorData: 'customer-123',
consents: [
{
type: 'general',
approved: true,
text: CONSENT_TEXT,
timestamp: '2026-05-08T10:00:00Z',
},
],
},
};
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',
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
Compressing payloads that don't need it. For small session-creation payloads without a long consent text, the compression overhead is rarely worth it. Reach for compression when consent text or other large string fields push the body well beyond a few KB.
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.
Changelog
Date | Description |
|---|---|
June 15, 2026 |
|
June 3, 2026 |
|
May 19, 2026 | "Payload compression" info added
|
Apr 24, 2026 | Headers capitalization harmonized |
Apr 17, 2026 | Typo fixes |
Apr 13, 2026 | New parameters added to support the Metadata Database Verification solution session generation: to |
Mar 18, 2026 |
|
Mar 9, 2026 | Documentation updated: parent categories rearranged, intro section expanded, request and response examples added |
Jan 6, 2026 | New parameter |
Nov 6, 2025 | "Article Versoning" renamed to "Changelog" |
Oct 30, 2025 |
|
Sep 16, 2025 |
|
Aug 6, 2025 | Response headers added |
Jul 11, 2025 | Improved the note in the intro section about session creation, and about finding request parameters from Product Guides |
Apr 30, 2025 | - New parameters added to request's - New header |
Apr 22, 2025 |
|
Mar 12, 2025 | Documentation published |