Verification Sessions
A session represents one identity verification. Creating it returns a widgetUrl you deliver to your customer, and a sessionId you use to correlate the result.
Create a Session
Endpoint: POST /v1/sessions
Authentication: Bearer token with the sessions scope
curl --request POST \
--url https://{FQDN}/v1/sessions \
--header "Authorization: Bearer $ACCESS_TOKEN" \
--header 'Content-Type: application/json' \
--data '{
"userRef": "user-123",
"language": "es",
"delivery": { "mode": "webhook" }
}'
{
"sessionId": "9f1c8e42-7c3e-4f2b-9d7a-2b1e5c8f4a10",
"status": "pending",
"widgetUrl": "https://{FQDN}/verify/8Kd2mQβ¦"
}
Request Fields
| Field | Type | Required | Description |
|---|---|---|---|
userRef | string (1-255) | Yes | Your identifier for the person being verified. Echoed back in every result |
prefill | object | No | Known data about the person β see Prefill |
dataCheck | boolean | No | false (default) verifies the document as presented. true additionally compares extracted data against prefill β see Data Checks |
delivery | object | No | How the result reaches you. Defaults to {"mode": "webhook"} |
language | string | No | Widget language, xx or xx-XX (e.g. en, pt, es, pt-BR). Falls back to your configured default |
maxCaptureAttempts | integer (1-10) | No | Overrides your tenant default for this session only |
Response Fields
| Field | Description |
|---|---|
sessionId | Use this to correlate results and to call GET /v1/sessions/{sessionId} |
status | Always pending on creation |
widgetUrl | The customer-facing link. Contains a single-use code valid for 48 hours |
Prefill
prefill carries what you already know about the person. It has two distinct effects.
| Field | Effect |
|---|---|
documentType | passport, drivers_license, or identity_card. Locks the widget to this document β the type-selection screen is skipped, and a different document is rejected. Omit it to let the customer choose |
documentNumber | Validated for format at this call (see below), and available for cross-checking |
issuingState | US state code or name for driver's licenses; ISO 3166-1 alpha-3 country for passports and identity cards. Sharpens format validation |
nationality | ISO 3166-1 alpha-3. Used to resolve the jurisdiction when issuingState is absent |
firstName, lastName | Available for cross-checking |
dateOfBirth | YYYY-MM-DD. Available for cross-checking |
{
"userRef": "user-123",
"prefill": {
"documentType": "drivers_license",
"issuingState": "PA",
"documentNumber": "31612967",
"firstName": "Ana",
"lastName": "Silva",
"dateOfBirth": "1988-03-04"
}
}
Prefill fields other than documentType do not change the decision unless you set dataCheck: true. Without it, the values are carried for comparison and reported in the result, but a mismatch does not route the session anywhere.
prefill.documentNumber is validated at this call, however: a number that violates its jurisdiction's known format is rejected with 422 rather than accepted and failed later. Check a number before you get here with the validator endpoint.
Data Checks
Set dataCheck: true to verify that the document belongs to the person you expected β not just that the document is genuine.
{
"userRef": "user-123",
"dataCheck": true,
"prefill": {
"firstName": "Ana",
"lastName": "Silva",
"dateOfBirth": "1988-03-04"
}
}
With dataCheck: true:
- Extracted data is compared field by field against the prefill payload.
- The result carries
prefillComparison(per-field outcomes, including fuzzy name-match scores) andprefillMismatches(the field names that disagreed). - A mismatch adds a failing soft check, routing the session to
in_reviewrather than declining it.
Names are compared with fuzzy matching against a configurable similarity threshold, so ordinary spelling and transliteration variance does not create false mismatches. dataCheck: true without a prefill payload is a 422 β there would be nothing to compare against.
Delivery
| Mode | Fields | Behavior |
|---|---|---|
webhook (default) | β | The result is POSTed to your configured webhookUrl |
redirect | redirectUrl (required) | The customer is returned to your URL with the outcome and a signature |
{ "delivery": { "mode": "redirect", "redirectUrl": "https://you.example/kyc-done" } }
Requesting webhook mode without a webhookUrl configured for your tenant is a 422. See Receiving Results for signature verification in both modes.
Error Responses
All of these return 422 with a detail explaining the specific cause:
| Cause | Notes |
|---|---|
delivery.mode is webhook but no webhookUrl is configured | Ask Inyo to register your endpoint, or use redirect mode |
delivery.redirectUrl missing in redirect mode | Required whenever mode is redirect |
documentType is not enabled for your tenant | The message lists the document types you may request |
| The document's issuing jurisdiction is not accepted for that document type | The message lists the jurisdictions you accept |
prefill.documentNumber failed format validation | The message names the rule that rejected it |
dataCheck: true with no prefill payload | Provide at least one comparable prefill field |
Authentication and authorization failures return 401 or 403 β see Authentication.
Retrieve a Session
Endpoint: GET /v1/sessions/{sessionId}
Authentication: Bearer token with the sessions scope
This is the authoritative record of a verification. Poll it when you need a guarantee rather than a push, to reconcile a webhook you may have missed, or to read the outcome of a session that went to manual review.
curl --request GET \
--url https://{FQDN}/v1/sessions/$SESSION_ID \
--header "Authorization: Bearer $ACCESS_TOKEN"
{
"sessionId": "9f1c8e42-7c3e-4f2b-9d7a-2b1e5c8f4a10",
"userRef": "user-123",
"status": "in_review",
"step": "done",
"deliveryMode": "webhook",
"result": { "β¦": "the normalized result, updated in place" },
"createdAt": "2026-07-31T14:02:11.481Z",
"updatedAt": "2026-07-31T14:04:57.902Z"
}
| Field | Description |
|---|---|
status | pending, approved, declined, in_review, or expired |
step | How far the customer got: document_front, document_back, selfie, or done |
deliveryMode | webhook, redirect, or sync (a server-to-server verification) |
result | The full normalized result once available, null before then. Updated in place when an analyst decides |
Sessions are strictly tenant-scoped. Another tenant's sessionId returns 404 β never a partial disclosure.
Next Steps
- Document Number Validator β check a number before you get here
- Widget Delivery β getting the customer through the flow
- Receiving Results β webhook and redirect handling
