Create a session
Mints a hosted verification link for one applicant from one of your published workflows, entirely server to server. You get back a URL that is theirs alone: send it by email, SMS, WhatsApp, or render it as a QR, and the applicant completes the flow on our hosted page with no SDK integration on your side.
The session is the link. It carries one verification, it is traceable to your own reference for the applicant, and once it is submitted it is spent. Forwarding it to a second person does not work. This is the API twin of the dashboard’s “Create session” action; the two accept the same request and mint the same thing.
Authentication: Authorization: Bearer sk_… (secret key required). The response contains a live verification credential and the request may carry applicant details, so this endpoint is backend-only. A publishable key receives 403 secret_key_required.
Content type: application/json.
Production note: sk_live_ keys require an approved business.
Looking for one URL many people can open, each visit starting its own verification? That is a workflow’s hosted link. This endpoint is the opposite shape: you know the applicant, and you want a link that is theirs.
Request body
A biometric-authentication workflow must name its subject at mint time: pass externalUserId for a user with an active biometric enrolment, or faceReferenceMediaId with a reference photo. Neither present is refused with 422 user_reference_required; a reference without an enrolment with 422 not_enrolled. A biometric-enrolment workflow always requires externalUserId (the template binds a face to a named record). This is checked when the session is created, so a link that could only fail at submit is never minted.
Request
Response 201 Created
The config the applicant walks is the workflow’s published snapshot, frozen at mint time. Editing or re-publishing the workflow never changes a link that is already in someone’s inbox.
Tracking the session
The sessionId doubles as the verification’s id once the applicant submits, so the reference you hold from the start resolves from the start:
GET /status/:idreports the attempt live:in_progresswith the current step and captured slots, then the full verification lifecycle after submission, andabandonedorexpiredif the applicant never finishes.- Session webhooks (
session.started,session.resumed,session.abandoned,session.expired) push the same lifecycle to your backend, and the verification events follow once they submit. - Opening the
urlin a WebView or an iframe? The page tells its host what the applicant is doing, step by step, with nothing to install: see Hosted link events. - Sending the
urlyourself over WhatsApp, SMS or email? It previews as your request: your organisation’s name and logo, the workflow’s primary colour and “Verify your identity with {Your organisation}” in the title, the same way a hosted link does. A spent or expired session previews as a neutral Toden card.
Ending a session early
A session you no longer want opened can be expired with POST /api/kyc/sessions/:sessionId/expire: the link stops working at once and you receive session.expired. To stop one reversibly instead, cancel it with POST /api/kyc/sessions/:id/cancel and uncancel it later. See Delete, expire & cancel.