KYC
Identity verification checks, the issuance gate, and console attestation.
The KYC gate
Creating a cardholder does not itself clear them to hold a card. Under a
programme with KYC enabled, card issuance requires the cardholder's
kyc_complete field to be true — and it is once the cardholder has either
passed verification (kyc_state: "passed") or been
attested by a console admin.
Three cardholder fields tell the story. kyc_state records what the
verification engine concluded (unverified, pending, in_review, passed
or failed); attested records a console admin's override; kyc_complete
derives from the two. When deciding whether issuance can proceed, read
kyc_complete — an attested cardholder keeps kyc_state: "unverified"
because attestation is an exemption from verification, not a verification
verdict.
Verification checks
A verification case is opened with Start a KYC check, which pins the check to the programme's active policy version and begins collecting applicant data. Attach that data with Attach applicant data — it is stored under purpose-bound custody and referenced by token, and API clients are the intended intake path: your backend collects from your user and submits on their behalf.
The case advances to evaluation once the policy has the inputs it requires,
then completes on its own. A check's public state moves through pending
while collecting and evaluating, and ends passed, failed, or in_review
when the policy refers it to a human. A case left without its required inputs
eventually ends expired (ageing is visible via created_at and
expires_at on the check).
Follow a single check with Retrieve a KYC check,
which includes reason_codes drawn from the evidence recorded against it, or
list the tenant's checks with List KYC checks —
oldest first, filterable by state and programme.
Document capture
Where a check needs a captured identity document, mint a capture session with Mint a capture-widget session token. It returns a single-use, 15-minute bearer token scoped to that one check — hand it to the hosted capture widget, never your own OAuth client credentials, so the widget can post the captured image on your behalf. A session is only mintable while the check is still collecting.
Programme policy
Each programme carries a KYC policy — which signals a check must produce before it can pass. Get the active KYC policy returns the current version, seeding version 1 from the platform default on first read; policy is scoped per programme and per mode, so test and live carry independent histories.
Policy versions are immutable.
Write a new policy version recomposes the
policy from the active version plus your requested required_signals set —
you toggle signals on or off, and the server owns how their evidence is
weighted. Checks in flight stay pinned to the version they started under.
Referred checks
A check the policy cannot settle lands in_review, and someone must decide
it. Record a decision resolves a referred case
to approved or rejected, and requires a named human reviewer — the
authenticated caller is recorded as the actor and may act on the reviewer's
behalf. Deciding emits a second kyc.check.completed event with a newer
checked_at.
For adjudication and audit, List evidence shows per-signal findings in production order (which signal produced which finding, under which engine version, with what score and reason codes), List decisions shows the decision history (the policy decision first, then any human decision), and Read submitted applicant data returns the human-adjudication slice of the applicant's data — every read of it is reported to the platform's PII audit pipeline.
Attestation
Where a programme has verified a cardholder out of band, a console admin can
record that as an attestation
(Attest a cardholder) from the
console's cardholder list. Attestation is an admin-only override of the KYC
gate: it is not reachable by any API client, org-wide or programme-pinned —
an unattended integration can never self-attest the cardholder it
represents. It flips kyc_complete to true while kyc_state continues to
record what the verification engine concluded.
Webhook events
Three events cover the check lifecycle:
kyc.check.started when a case
opens, kyc.check.completed
when it settles (and again if a referred case is later decided), and
kyc.check.expired when an
unfinished case ages out. Wait for kyc.check.completed rather than polling
Retrieve a KYC check; delivery, verification and
retries work as described in the webhooks guide.