Identity documents
Identity documents do not pass through this API. This page explains what that means for you.
Before you begin
Read KYC lifecycle and statuses first. This page covers the half of verification that happens entirely on your side.
How it works
There is no document upload endpoint, and that is a design decision rather than a gap.
Verification is yours to run. The cardholder submits their passport, license, or selfie to your identity provider, through that provider's own hosted flow or SDK. Those images and extracted fields stay with you and your provider. What reaches us is the attestation — an assertion that verification happened, by whom, when, and with what result.
Nothing crosses the boundary into /v1 except the attestation.
Why it is built this way
Identity documents are among the most sensitive data a fintech handles — a passport image is a lifetime credential, not a resettable one. Every system that stores one inherits obligations around retention, residency, access control, and deletion.
Keeping them out of our pipeline means:
- Your compliance footprint is yours, and does not have to accommodate ours
- Data residency stays where you put it. No copy crosses a border because our infrastructure sits somewhere else
- A breach here does not expose your cardholders' identity documents, because we do not hold them
- Deletion requests are single-party. You erase your copy; there is no second system to chase
What we hold instead
| We hold | We do not hold |
|---|---|
| The attestation: status, timestamp, provider, reference, method | Document images or scans |
custIdType / document type, where your program supplies it | Document numbers |
| Contact details and address on the cardholder | Extracted biometric or MRZ data |
| The full attestation chain over time | Anything your provider returned beyond the outcome |
Steps
1. Collect documents through your provider
Use their hosted flow or mobile SDK. Do not build your own capture pipeline unless you have a reason to — the providers handle liveness, tamper detection, and document parsing, which are not casual problems.
2. Report the outcome, not the evidence
curl -X POST "$ALETA_BASE_URL/v1/cardholders/chd_01HX8ZQ2K4M7P9RSTVWXYZAB/kyc" \
-H "Authorization: Bearer $ALETA_ACCESS_TOKEN" \
-H "Idempotency-Key: $(uuidgen)" \
-H "Content-Type: application/json" \
-d '{
"status": "approved",
"verified_at": "2026-07-29T11:04:00Z",
"provider": "Acme Identity",
"provider_reference": "chk_9f31c7",
"method": "document_and_selfie"
}'
provider_reference is the hinge. It is what lets someone holding our record
ask you for the corresponding check, and lets you find it.
3. Do not send documents anyway
The API has no field that accepts them. Requests carrying unrecognized fields
are rejected with unknown_parameter, not silently ignored — so an attempt
to attach a base64 image fails loudly rather than quietly landing somewhere it
should not.
notes is not a smuggling routenotes exists for operational context: "manual review by compliance, ticket
4471".
Putting a document number, an MRZ string, a date of birth extracted from a passport, or a base64 image in there defeats the entire boundary this page describes. It is a 500-character free-text field, and it is audited like every other field.
4. Retain your side properly
We cannot tell you your retention period — it depends on your regulator, your markets, and your own policy. What we can say is what the attestation assumes:
- Retain the underlying evidence at least as long as the attestation is in force. An attestation pointing at a check you have deleted is not evidence.
- Keep
provider_referenceresolvable. If you change providers, keep the old records addressable rather than orphaning every historical attestation. - Log who submitted each attestation on your side. We record that your organization asserted it; only you know which of your staff or systems did.
Verifying
- A cardholder with a reported outcome shows the expected
kyc_status GET .../kycreturns your attestation with the provider reference intact- An attempt to send a document field returns
unknown_parameter - Given a
provider_referencefrom our record, you can locate the original check in your provider's system
That last one is the real test. Do it once, deliberately, before go-live — it is exactly what an audit will ask you to demonstrate.
What an auditor asks each side
| Asked of you | Asked of us |
|---|---|
| The documents and the provider's check | The attestation chain per cardholder |
| Who ran verification and under what policy | When each was recorded and by which organization |
| Evidence the person matches the documents | That no card was activated without an approved attestation |
The two halves join on provider_reference. Neither side is complete alone,
which is why that field is worth treating as mandatory even though the API
marks it optional.
Common errors
| Status | code | Fix |
|---|---|---|
400 | unknown_parameter | You sent a field the API does not accept — including any attempt at a document payload |
422 | kyc_provider_required | The attestation must name who verified |
422 | kyc_attestation_incomplete | Missing status or verified_at |