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/*:
Authorization: Bearer sk_test_your_key_hereKeys 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:
{
"error": {
"type": "invalid_request_error",
"code": "parameter_invalid",
"message": "required_age: Invalid input"
}
}| Field | Type | Description |
|---|---|---|
error.type | string | One of the four categories below. |
error.code | string | A stable, machine-matchable code — safe to branch on. |
error.message | string | Human-readable detail. Not present on every error; never parse it. |
| Field | Type | Description |
|---|---|---|
authentication_error | 401 | invalid_api_key — the bearer token is missing or doesn’t match a key on file. |
invalid_request_error | 400 / 404 | parameter_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_error | 429 | rate_limited — see Rate limits below. |
api_error | 500 | internal_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
/v1/verification-sessionsCreate a sessionCreates a hosted verification session and returns its one-time url. The session expires 30 minutes after creation if never started.
Request body
| Field | Type | Description |
|---|---|---|
required_agerequired | 16 | 18 | The minimum age this session must confirm. |
methods | string[] | 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_urlrequired | string | An http(s) URL. The hosted flow redirects here when the session finishes, with ?session_id=vs_... appended. |
metadata | object | Up 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
{
"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": {}
}/v1/verification-sessions/:idRetrieve a sessionFetch 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
{
"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.
/v1/verification-sessionsList sessionsCursor-paginated, newest first.
| Field | Type | Description |
|---|---|---|
limit | integer | 1–100. Defaults to 20. |
cursor | string | From the previous page's next_cursor. |
Response — 200 OK
{
"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.
/v1/webhook-endpointsCreate an endpoint| Field | Type | Description |
|---|---|---|
urlrequired | string | Must be https — plain http endpoints are rejected. |
events | string[] | Any of verification_session.completed, verification_session.expired. Defaults to both. |
Response — 201 Created
{
"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.
/v1/webhook-endpointsList endpoints{
"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"
}
]
}/v1/webhook-endpoints/:idDelete an endpointReturns 204 No Content. 404 (resource_missing) if the id doesn’t belong to your org.