Skip to main content
Know Your Customer (KYC) verification is required before a user can receive payments through Cadana. You submit identity documents and personal information via the API, and Cadana handles automated verification. This page covers the submission requirements, status tracking, and webhook events.

KYC Flow

Most verifications complete automatically within minutes. pending means automated checks could not verify the user, so a reviewer has to decide — allow 1-2 business days for it to settle into approved or rejected.

Submit KYC

Submit identity information and documents for a user. Upload document images first using the file upload flow, then pass the returned fileId values. Returns 204 on success. The user’s KYC status moves to processing.

Personal Information

Identity Document

Supported document types:
Images must be clear and readable with all text visible. Supported formats: JPEG, PNG.

Address (Optional)

If provided, all required address fields must be completed. An address proof document can be provided via addressProofFileId (utility bill, bank statement, or government document dated within the last 3 months).

Check KYC Status

Retrieve a user’s current KYC status. Response:
Identity and address verification are tracked separately. A user needs at minimum identity: "approved" to receive payments. Note that address is the verification status of the address, while userAddress holds the address itself.

Timestamps

The six timestamp fields are formatted as YYYY-MM-DD HH:MM:SS +0000 UTC, always in UTC. This is not RFC 3339, so parse it with an explicit layout rather than a standard ISO 8601 parser. Any of these is an empty string when the corresponding event has not happened — for example, lastAddressSubmissionDate stays "" until the user submits an address.

Resubmit KYC

If a user’s identity or address verification is rejected, use the PATCH endpoint to resubmit corrected information. You can resubmit identity, address, or both in a single request. Resubmission rules:
At least one of identity or address must be provided. When a section is included, all of its fields are required.

Resubmit identity only

Resubmit address only

Returns 204 on success. Only the resubmitted section(s) move to processing — approved sections remain unchanged.

Webhook Events

user.kyc.updated

Fired on every KYC status change — processing, pending, approved, or rejected. The type field indicates which verification component changed.
For rejected verifications, have the user resubmit the affected section with the PATCH endpoint.

user.kyc.expiry

Fired when a user’s identity document is approaching expiry or has expired.
The event fires once per stage, when the document first enters it — not repeatedly while it stays there. Expect three events per document: one when it enters about-to-expire, one on the expiry date, and one when the grace period runs out. To remind users as the date approaches, drive your own schedule off the expiryDate in the payload rather than waiting for another event.
See Events for all event types and payload details.

Handling Rejections

When KYC is rejected, the user needs to resubmit. Common rejection reasons: To resubmit, call PATCH /v1/users/{userId}/kyc with corrected information for the rejected section(s). The status resets to processing.

Sandbox Testing

Use sentinel values to simulate KYC approval or rejection in the sandbox environment without waiting for real verification. These sentinels work with both initial submission (POST) and resubmission (PATCH).
In sandbox, a submission without a sentinel never gets a result on its own — the user stops at pending. PATCH cannot move them, because resubmission only works after a rejection. So either use a sentinel, approve them yourself, or delete the sandbox user and start over.

Identity Verification

Set idDetails.number to a sentinel value:

Address Verification

Set address.line2 to a sentinel value: You can combine both sentinels in a single request to auto-resolve identity and address independently. For example, idDetails.number: "auto-approve" with address.line2: "auto-reject" will approve identity and reject address.
When a sentinel is used, the document file IDs (frontFileId, selfieFileId, addressProofFileId) can be omitted — no file upload is needed. If you do pass them, they must reference files you actually uploaded; made-up IDs are rejected with a 404. Without a sentinel, file IDs are required, as in production.

Testing the Resubmission Flow

To test the full rejection-to-resubmission cycle in sandbox:
  1. Submit KYC with idDetails.number: "auto-reject" to get a rejected identity
  2. Resubmit via PATCH with idDetails.number: "auto-approve" to approve it
These test values only work in the sandbox environment and are silently ignored in production. Sentinel values are case-insensitive.

Testing Document Transfer

A sentinel tells Cadana the answer up front, so your uploaded files are never opened. That is quick, but it means a sentinel cannot prove your document upload works. To test the upload itself, submit the way your production code would — real ID number, real fileId values, no sentinel. Cadana stores the documents and sends them on for verification. Sandbox has no real reviewer, so the user stops at pending and waits. Approve them yourself to finish: Set action to approve or reject, and type to identity or address. Each call decides one check, so approving both takes two calls. It works from any status — including pending, which resubmission cannot rescue — and it fires user.kyc.updated just like a real result. For the full step-by-step version of this flow, plus what to do when a test user gets stuck, see Sandbox & Testing.

Next Steps

Working with Files

Upload identity documents before submitting KYC

KYB Requirements

Business verification requirements

Onboard Workers

Create Person and User records

Sandbox & Testing

Test values and simulated scenarios