Skip to content

API

Errors and limits

One error envelope, eight codes, and every limit the API enforces.

Every error, from every endpoint, has the same shape. code is stable and machine-readable; message is a sentence for people and may change.

json
{ "error": { "code": "not_found", "message": "Session not found" } }
HTTPcodeWhenRetry?
400bad_requestMalformed JSON or multipart, or a field fails validationNo: fix the request
401unauthorizedMissing, unknown or revoked API key; expired console sessionNo: check the key
403forbiddenYour console role may not do thisNo
404not_foundNo such resource in your app (or organisation)No
409conflictWrong state: deciding a session not in review, uploading after submitAfter reloading the state
422unprocessableUnderstood but refused: no face in an image, an MRZ that cannot be parsed, a document type the workflow does not acceptWith different input
429rate_limitedToo many requests in the windowYes, after the window
500internalSomething failed on the server; details are logged, not returnedYes, with backoff

Handling errors

Node.js · javascript
const res = await fetch(url, init);
if (!res.ok) {
  const { error } = await res.json();
  switch (error.code) {
    case "rate_limited":
    case "internal":
      return retryWithBackoff();
    case "conflict":
      return reloadAndDecide();
    default:
      throw new Error(`${res.status} ${error.code}: ${error.message}`);
  }
}

Limits

WhatLimit
Hosted flow requests60 per minute per session token
Console sign-in10 attempts per minute per IP and email; 20 failed attempts per hour per account
Sign-up20 per hour per IP, 200 per hour across the service
Email verification codes10 per hour per address; 50 (sandbox) or 500 (live) per hour per organisation
Request body40 MB (multipart with several frames)
Each upload10 MB; JPEG, PNG, WebP or ZIP by content, not extension
Image dimensions8,192 pixels a side and 24 megapixels, read from the header before decoding
Liveness frames16 per attempt
vendor_data · metadata256 characters · a JSON object up to 8 KB
expires_in_hours1 to 720
page_size1 to 100, default 25
Review note2,000 characters
AML full_name300 characters

Rate limits are kept in process memory. The public /v1 API has no per-key rate limit today; if you plan sustained high volumes, tell us first.

Pagination

List endpoints return { data, page, page_size, total }. Request the next page while page * page_size < total.