REST API: KYC
Database check results
Poll for AML and other database check verdicts.
Purpose
Database checks run after the session itself finishes. Use this call to read their results, or receive the DATABASE_CHECKS_COMPLETE webhook, which carries the same checks in a flatter shape: the verdict fields sit on the entry of results itself, not under result. The webhook is one notification with the full result set, sent once all checks of the session are terminal, and it is sent again whenever the session returns to a fully terminal state, so treat it as idempotent by sessionId. For the AML side see AML screening: retrieving the result.
Request
POST <API_BASE_URL>/kyc/session/databases. All calls are POST under your API address. Replace <API_BASE_URL> with the API address provided with your access.
Send a permanent API token in the token field of the body, or a user token in the token header. See authentication.
Content type: application/json.
| Field | Type | Required | Description |
|---|---|---|---|
token | string (uuid) | if no header | Your permanent API token. Required unless you send a user token in the token header. |
sessionId | string | one of two | The session identifier, or the questionnaireSessionId of a questionnaire record. |
clientKey | string | one of two | Your client key, for regular sessions only. It resolves the latest session with this key. |
Response
HTTP 200. The check results for the identifier you named.
| Field | Type | Description |
|---|---|---|
sessionId | string (uuid) | The session the checks belong to. |
checksStatus | string | complete means polling can stop; pending means keep polling. On a session, complete needs the session to be terminal as well as every check, so an abandoned session never reaches it: its stored status stays idle. Stop when the session lifetime that you set has passed. On a questionnaire record, complete needs the record to be committed, no check pending and the set of checks settled. A record has no lifetime, so wait for the webhook instead of polling to a deadline. A scenario with no checks answers complete with an empty results. |
pending | number | How many checks in results are not final yet. |
results | array of object | One entry per check. |
results[].checker | string | The identifier of the check. The DATABASE_CHECKS_COMPLETE event sends the same value, so you can match polled results to webhook payloads. |
results[].status | string | The check status: idle, processing, success, failed or exception. |
results[].outcome | string | performed, skipped or unavailable, and null while the check is not finished. Read it before passed. |
results[].notPerformedReason | string | Why there is no result. Null when outcome is performed. |
results[].missingInputs | array of string | The input data the check needed and did not get. |
results[].result.passed | boolean | The verdict of the check. |
results[].result.items | array of object | The matched records, if any. |
results[].result.totalCount | number | The number of matches. |
results[].result.error | string | An error text from the check, when there was one. |
Skipped is not clean. A check that never ran arrives with status of success and passed of null. Tell "not checked" and "checked, clean" apart by outcome, notPerformedReason and missingInputs, never by passed alone.
outcome values: performed means the source was queried and the result is meaningful. skipped means the check did not run because input data was missing or unusable, so an empty result means not checked. unavailable means the source failed or could not be reached, and a re-run can succeed.
notPerformedReason values: missingInput, unusableInput, identityUnresolved, ageBelowDocumentAge, providerUnavailable, providerError and unknown. For missingInput, supply the data that missingInputs names and run again.
After an erasure request the object keeps its identifiers, statuses and verdicts and carries no personal values: pdErased is true.
Errors
400: The body failed validation. The answer hasstatusoferrorand adetailslist with one entry per offending field (path,expected,actual).401: The token is missing, expired or unknown.500: An unexpected internal failure. The answer hasstatusoferrorand the fixed textinternal error; nothing in the body helps you branch beyond the code.
A refusal can also come before the operation runs: an address outside your IP allowlist, a token bound to another address, or a body that is not valid JSON. See response format and errors.
Example
Request:
curl -X POST "<API_BASE_URL>/kyc/session/databases" \
-H "Content-Type: application/json" \
-d '{
"token": "<your permanent API token>",
"sessionId": "00000000-0000-0000-0000-000000000000"
}'
Response:
{
"sessionId": "00000000-0000-0000-0000-000000000000",
"checksStatus": "complete",
"pending": 0,
"results": [
{
"checker": "<check identifier>",
"status": "success",
"outcome": "performed",
"notPerformedReason": null,
"missingInputs": [],
"result": {
"passed": true,
"items": [],
"totalCount": 0
}
}
],
"responseTime": "2026-01-01T10:05:00.000Z"
}