Get verification status
Build with

code
GET /api/kyc/status/:verificationId

Returns the minimal lifecycle state of a verification. status is the merged top-line (not_started, in_progress, processing, in_review, awaiting_resubmission, approved, declined, abandoned, expired, error) and checkStatus is what the checks themselves found (pending, verified, failed, not_found, error). They differ when a person overrode the automated result. See Status and checkStatus.

This endpoint is publishable-safe: it can be called with the pk_ key that ships in your SDK, so it deliberately returns no PII, no match scores, and no result data. To read the full result + extracted biodata, use Get verification result with a secret (sk_) key from your backend.

Webhooks are the recommended way to learn about completion without polling.

Authentication: Authorization: Bearer pk_… or sk_… (required). A verification is only visible to the organisation that created it.

Request
Build with

shell
curl "https://trust.myaza.app/api/kyc/status/ver_01j9..." \
  -H "Authorization: Bearer $MYAZA_PUBLISHABLE_KEY"

Responses
Build with

Every response includes verificationId, status, createdAt, your externalUserId (so a publishable key can tell which user an id belongs to; your metadata stays on the secret-key result), and the workflow attribution pair workflowId / workflowVersion (both null when the SDK was configured with plain props instead of a workflow).

processing / approved

json
{
  "verificationId": "ver_01j9...",
  "status": "approved",
  "checkStatus": "verified",
  "externalUserId": "user_42",
  "workflowId": "wf_AbC123dEf456",
  "workflowVersion": 3,
  "createdAt": "2026-04-27T12:00:00.000Z",
  "completedAt": "2026-04-27T12:00:05.000Z"
}

workflowVersion is the published version that actually ran. Publishing a workflow overwrites its live configuration in place, so keep the pair if you need to explain later exactly which rules a submission went through. The workflow's human-readable name is on the full result; this endpoint stays minimal.

An approved status confirms the person was accepted, but carries no identity data. Fetch the full result with a secret key to read the biodata and facial-match score.

approved with checkStatus: "failed" is not a contradiction. It means a person reviewed the verification and accepted it despite what the checks found, and reason/reasonCode below say what they accepted it despite. Branch on status; store checkStatus alongside it.

declined / error

declined means the person was not accepted, either because the checks did not pass or because a reviewer declined them. error means a system problem occurred on our side and you were not charged. Both include a human-readable reason and a stable reasonCode you can branch on. See failure reason codes.

A reason is present whenever the checks did not pass, even on a verification a reviewer later approved.

json
{
  "verificationId": "ver_01j9...",
  "status": "declined",
  "checkStatus": "failed",
  "reason": "The user's selfie does not match the photo on file with the government database (match confidence 48%, minimum 70% required).",
  "reasonCode": "selfie_mismatch",
  "createdAt": "2026-04-27T12:00:00.000Z",
  "completedAt": "2026-04-27T12:00:05.000Z"
}

declined with identity_not_found

An ID number the government database does not hold is a decline like any other; the reasonCode is what tells it apart from a failed face match. There is no separate not_found status.

json
{
  "verificationId": "ver_01j9...",
  "status": "declined",
  "checkStatus": "not_found",
  "reason": "The BVN number was not found in the government database.",
  "reasonCode": "identity_not_found",
  "createdAt": "2026-04-27T12:00:00.000Z",
  "completedAt": "2026-04-27T12:00:05.000Z"
}

Errors
Build with

StatusBodyCause
404{ "error": "Verification not found" }Unknown ID, or it belongs to another organisation.
401{ "error": "Invalid API key" }Auth failed.

Polling guidance
Build with

If you must poll, do so with backoff (e.g. every 2–3 seconds, widening over time) and stop once status is no longer pending. Prefer webhooks for production. Once complete, fetch the full result from your backend.