A verification session represents one identity verification you want to perform. You create a session via the API, redirect the user to the session’sDocumentation Index
Fetch the complete documentation index at: https://docs.kayle.id/llms.txt
Use this file to discover all available pages before exploring further.
verification_url, and receive the result over a webhook when the user finishes — or a verification.session.expired event if they don’t.
The session object
The shape returned by the API:cancel_token is returned only at creation. The verify URL embeds it as a query parameter so the verify browser and native apps can pass it back when cancelling. If you want to surface a cancel link from somewhere else (a dashboard, an email), store it server-side at creation time.
Lifecycle
A session moves through these statuses:| Status | Meaning |
|---|---|
created | The session exists. No attempt has been claimed yet. |
in_progress | A mobile or web client is actively performing the verification. |
completed | An attempt succeeded, or the maximum number of attempts was exhausted with no success. |
expired | 60 minutes elapsed since creation without a terminal attempt. |
cancelled | The session was cancelled by you or by the user. |
created_at. A scheduled job sweeps expired sessions and emits verification.session.expired for any that didn’t reach completed or cancelled first.
Attempts
Inside a session, each interactive run by the user is an attempt (va_...). An attempt has its own status — in_progress, succeeded, failed, cancelled — and, on failure, a failure_code you can match on. See Document checks for the codes.
A session allows up to three attempts. After the third terminal failure, the session moves to completed and no further attempts are accepted.
You can fetch attempts attached to a session with ?include_attempts=true on GET /v1/sessions/:id, or list across sessions via GET /v1/sessions/attempts.
Creating a session
share_fields is optional. If you omit it, the session uses Kayle’s default share contract (a minimal set including kayle_document_id). If you include it, every entry needs required and a non-empty reason (200 characters max). See Share fields for the catalogue.
redirect_url is also optional, but it must begin with https://.
Both fields are reflected back to the user during the consent step, so write reason strings the user will see and trust.
Cancelling
Two cancel paths exist:- Authenticated cancel —
POST /v1/sessions/:id/cancelwith your API key. Idempotent. Use this when you decide server-side that you no longer want the verification to proceed. - Public cancel —
POST /v1/verify/session/:id/cancelwith the one-shotcancel_tokenin the body. The verify app and native apps use this to abort from the user’s side. The token is consumed on first successful use; subsequent calls return204if the session is already terminal, otherwiseCANCEL_TOKEN_USED.
verification.session.cancelled to subscribed webhooks.
The
verification_url in the create response already contains cancel_token as a query parameter, so you don’t need to surface it yourself unless you’re building a separate cancel UI.Listing sessions
GET /v1/sessions supports filtering by status, created_from, and created_to, and follows the standard cursor pagination (limit, starting_after, next_cursor). Pass include_attempts=true to attach the attempt array to each session — handy for reporting, but increases payload size.
What you don’t see
The session object never includes raw document data, MRZ fields, the on-chip portrait, selfies, or the face match score. Those are computed and discarded inside the verification pipeline. The only place verified claims surface is in theverification.attempt.succeeded webhook payload.