API reference
Server routes use your App API key. Applicant-side routes (used by the hosted flow and by custom SDKs) are scoped by the unguessable session id.
Authentication
Server-to-server routes (init, info) require x-api-key: <App API key>. A company-level key also works as a fallback. Applicant-side routes do not use the key: the session id acts as the capability, so never log or share it publicly. Keys belong on your server only.
Create a session
See the quickstart for the body. Returns 201 with session, verificationUrl and resultPasskey. Additional optional fields: skipWelcomePage, enableAmerican (FATCA/US person question), enablePPE (PEP question), enableGeneralInformation, sessionInfo. Body values override App settings, which override defaults.
Errors: 400 invalid or missing field or unsafe webhook URL; 401 bad key; 402 monthly quota; 403 flow not enabled; 429 rate limit.
Get session info
Requires x-api-key. Returns the session (without resultPasskey) and the application data. 404 if unknown; 403 if the session belongs to another company.
{
"success": true,
"session": { "sessionId": "…", "status": "FINISHED", "decision": "APPROVED", "riskScore": 6, "…": "…" },
"application": { "…": "extracted fields, verification reports" },
"ephemeral": false
}Upload routes for SDK use
If you build your own capture UI instead of the hosted flow, use these routes. They are the same ones the hosted flow calls.
Document image
Multipart form with file (JPEG/PNG/WebP, max 10 MB), type=cin and side=front|back. PDFs are rejected on purpose. The response reports success or an errorCode (for example PDF_NOT_ACCEPTED, UNSUPPORTED_FILE_TYPE, DUPLICATE_CIN_NUMBER) that tells the user what to retake.
curl -X POST https://YOUR_HOST/api/session/SESSION_ID/upload \
-F "file=@front.jpg" \
-F "type=cin" \
-F "side=front"Selfie
JSON body { "image": "<base64>" }. A data-URL prefix is accepted. Returns { success: true, faceId }, or 400 on failure.
curl -X POST https://YOUR_HOST/api/session/SESSION_ID/selfie \
-H "Content-Type: application/json" \
-d "{\"image\": \"$(base64 < selfie.jpg | tr -d '\n')\"}"Update step
Only step (and optionally language) may be set. Status is always computed by the server; a status in the body is ignored. Steps can advance or repeat but not go backwards.
curl -X PATCH https://YOUR_HOST/api/session/SESSION_ID/update \
-H "Content-Type: application/json" \
-d '{"step": 3}'Errors
| Status | Meaning | What to do |
|---|---|---|
| 401 | Missing or invalid API key. | Check the x-api-key header and that the app is active. |
| 402 | QUOTA_EXCEEDED: monthly verification limit reached. Body includes limit and used. | Raise the plan limit or wait for the next month (UTC). |
| 403 | Flow not enabled for the account, or session belongs to another company. | Check allowed flows and which key you use. |
| 409 | Session is closed (APPROVED, DECLINED, EXPIRED), or a duplicate ID number. | Create a new session. |
| 413 | File larger than 10 MB. | Resize or compress the photo. |
| 415 | Unsupported file type, or a PDF. | Send a JPEG, PNG or WebP photo. |
| 429 | Rate limit hit. Retry-After header gives seconds. | Back off and retry. |
Rate limits
Limits are per client IP and per process, in fixed windows. They protect the service; do not design around them.
| Route | Limit |
|---|---|
POST /api/session/init | 60 requests / minute |
PATCH /api/session/{id}/update | 60 requests / minute |
POST /api/session/{id}/upload | 20 requests / minute |
Status lifecycle
| Status | Meaning |
|---|---|
INITIATED | Session created, user has not started. |
PENDING | User is in the flow (capturing or submitting). |
FINISHED | Applicant finished and every automatic check passed (auto-approve rules met). Webhook: verification.completed. |
VERIFICATION | Applicant finished but something needs manual review. Webhook: verification.review_required. |
APPROVED | Final: a reviewer (or the result-link holder) approved. Webhook: verification.approved. |
DECLINED | Final: a reviewer declined. Webhook: verification.declined. |
EXPIRED | Final: closed without a decision; no further uploads accepted. |
FINISHED means the automatic rules found nothing to flag (see auto-approval); it is not the same as APPROVED, which is an explicit decision recorded with the actor and an optional reason. A decision can be made from FINISHED or VERIFICATION and corrected later. Decisions are made in the admin console, or through PATCH /api/session/{id}/decision with a signed-in admin session or the result passkey; it is not an API-key route.