Docs · Reference

REST API

Base URL: https://5do9r1erj7.execute-api.ap-southeast-2.amazonaws.com. Every request and response body is JSON.

Authentication

Send your secret key as a bearer token on every request to /v1/*:

header
Authorization: Bearer sk_test_your_key_here

Keys start with sk_test_ or sk_live_. A test key only ever talks to the simulated providers (see Test mode) — nothing it does is billed, and it works with no card on file. A missing or invalid key returns a 401 with type: "authentication_error".

Errors

Every error response shares one envelope:

json
{
  "error": {
    "type": "invalid_request_error",
    "code": "parameter_invalid",
    "message": "required_age: Invalid input"
  }
}
FieldTypeDescription
error.typestringOne of the four categories below.
error.codestringA stable, machine-matchable code — safe to branch on.
error.messagestringHuman-readable detail. Not present on every error; never parse it.
FieldTypeDescription
authentication_error401invalid_api_key — the bearer token is missing or doesn’t match a key on file.
invalid_request_error400 / 404parameter_invalid (a request body/query failed validation), cursor_invalid (a list cursor is malformed or expired), or resource_missing (404 — no session/endpoint with that id for your org).
rate_limit_error429rate_limited — see Rate limits below.
api_error500internal_error — something failed on our side. Safe to retry.

Rate limits

100 requests per minute, per organisation, shared across every endpoint under /v1/*. Exceeding it returns a 429 with error.code: "rate_limited". There’s no separate test-mode limit — test and live keys for the same org share the budget.

Verification sessions

01POST/v1/verification-sessionsCreate a session

Creates a hosted verification session and returns its one-time url. The session expires 30 minutes after creation if never started.

Request body

FieldTypeDescription
required_agerequired16 | 18The minimum age this session must confirm.
methodsstring[]Any of face_estimation, id_document, credit_card, digital_id. Defaults to ["face_estimation", "id_document"]. The user tries them in order and escalates automatically on an inconclusive result. credit_card only applies when required_age is 18. digital_id is accepted but not yet live (roadmap).
return_urlrequiredstringAn http(s) URL. The hosted flow redirects here when the session finishes, with ?session_id=vs_... appended.
metadataobjectUp to 20 string key/value pairs (values ≤ 500 chars) echoed back on the session and on webhook events — e.g. your own order or user id.

Response — 201 Created

json
{
  "id": "vs_01ARZ3NDEKTSV4RRFFQ69G5FAV",
  "url": "https://d21c67ryshh77h.cloudfront.net/v/vs_01ARZ3NDEKTSV4RRFFQ69G5FAV#st=eyJhbGciOi...",
  "status": "created",
  "required_age": 18,
  "methods": ["face_estimation", "id_document"],
  "return_url": "https://yoursite.com/age/verified",
  "mode": "test",
  "created_at": "2026-07-12T04:00:00.000Z",
  "expires_at": "2026-07-12T04:30:00.000Z",
  "metadata": {}
}
02GET/v1/verification-sessions/:idRetrieve a session

Fetch a session’s current state — poll this, or call it after a redirect back to confirm the outcome before you act on it.

Response — 200 OK

json
{
  "id": "vs_01ARZ3NDEKTSV4RRFFQ69G5FAV",
  "status": "passed",
  "required_age": 18,
  "methods": ["face_estimation", "id_document"],
  "return_url": "https://yoursite.com/age/verified",
  "mode": "test",
  "outcome": {
    "method": "face_estimation",
    "result": "pass",
    "confidence": "high",
    "completed_at": "2026-07-12T04:00:31.000Z"
  },
  "attempts": 1,
  "created_at": "2026-07-12T04:00:00.000Z",
  "expires_at": "2026-07-12T04:30:00.000Z",
  "metadata": {}
}

status is one of created, in_progress, passed, failed, expired. outcome is present only once the session is terminal (passed/failed). attempts is a count, not the attempt log — no method-level detail beyond the final outcome is ever returned, by design.

03GET/v1/verification-sessionsList sessions

Cursor-paginated, newest first.

FieldTypeDescription
limitinteger1–100. Defaults to 20.
cursorstringFrom the previous page's next_cursor.

Response — 200 OK

json
{
  "data": [ /* SessionView, same shape as GET /v1/verification-sessions/:id */ ],
  "next_cursor": "eyJ2c0lkIjoi..." // omitted/null on the last page
}

Webhook endpoints

Manage where verification_session.completed/.expired events get delivered — see Webhooks for the delivery/signature scheme. You can also manage these from the dashboard.

01POST/v1/webhook-endpointsCreate an endpoint
FieldTypeDescription
urlrequiredstringMust be https — plain http endpoints are rejected.
eventsstring[]Any of verification_session.completed, verification_session.expired. Defaults to both.

Response — 201 Created

json
{
  "id": "whe_01ARZ3NDEKTSV4RRFFQ69G5FAV",
  "url": "https://yourapp.com/webhooks/ageassure",
  "events": ["verification_session.completed", "verification_session.expired"],
  "created_at": "2026-07-12T04:00:00.000Z",
  "secret": "whsec_9f3a2b1c..."
}

secret is returned only here, at creation — store it immediately. Every other response for this endpoint omits it.

02GET/v1/webhook-endpointsList endpoints
json
{
  "data": [
    {
      "id": "whe_01ARZ3NDEKTSV4RRFFQ69G5FAV",
      "url": "https://yourapp.com/webhooks/ageassure",
      "events": ["verification_session.completed", "verification_session.expired"],
      "created_at": "2026-07-12T04:00:00.000Z"
    }
  ]
}
03DELETE/v1/webhook-endpoints/:idDelete an endpoint

Returns 204 No Content. 404 (resource_missing) if the id doesn’t belong to your org.