Cardholders & Compliance

Every Cardholder moves through a compliance-driven lifecycle before any Card can be issued to them. This page covers the full status model, the two compliance paths (Didit-hosted KYC and SumSub), which fields become locked once review begins, and the documents collected as part of KYC.

📘

Recall from Program Architecture:

A Cardholder is always a natural person, even when, internally at least, the Program serves a corporate client.

The status model

statusNameMeaning
0PendingA transitional state between other statuses — generally brief, observed in passing during state changes rather than as a resting state
1ApprovedKYC passed — Cards can now be issued to this Cardholder
2Compliance DeclineKYC failed programmatically
3Under ReviewSubmitted for compliance review; awaiting outcome
4DraftCreated but not yet submitted for compliance review
5DeletedRemoved
6ErrorA processing error occurred during compliance review
7Admin DeclineManually declined

Lifecycle

stateDiagram-v2
		[*] --> (4)Draft: Create Cardholder POST /cardholders
    (4)Draft --> (4)Draft: Edit Cardholder PUT /cardholder/{cardholderId}
    (4)Draft --> (3)UnderReview: Submit to compliance POST /cardholders/{cardholderId}/kyc-submit
		(4)Draft --> (5)Deleted: DELETE /cardholders/{cardholderId}
    (3)UnderReview --> applicationLink
    state fork_state <<fork>>
		    applicationLink --> fork_state: Cardholder submits KYC
    		fork_state --> (1)Approved: Application succeeds
        fork_state --> NotApproved: Application fails
				NotApproved --> fork_state: Manual review
    state NotApproved {
		    [*] --> (2)ComplianceDecline: Automatically declined
		    [*] --> (7)AdminDecline: Manually declined
        [*] --> (6)Error: Processing error
		}
    NotApproved --> (4)Draft: Edit Cardholder PUT /cardholder/{cardholderId}
    NotApproved --> applicationLink: Refresh applicationLink POST /cardholders/{cardholderId}/ky-url/refresh
		NotApproved --> (5)Deleted: DELETE /cardholders/{cardholderId}
    (1)Approved --> [*]
   	(5)Deleted --> [*]

    note right of (4)Draft
        Status 0 (Pending) is a brief transitional state that may be observed during any of these transitions, rather than a resting state.
        end note
        
    classDef notStatus fill:white
		class applicationLink notStatus
    class Completed notStatus
    class NotCompleted notStatus
    class Expires notStatus
		class if_state notStatus

Only Cardholders with status = 1 (Approved) can have Cards issued to them — see Cards: Virtual & Physical and Issue a Virtual Card.

The onboarding sequence

sequenceDiagram
    participant You
    participant Axys
    participant Cardholder

    You->>Axys: POST /cardholders
    Axys->>You: cardholderId and Draft status

    Note over You,Axys: Optional edit while in Draft

    You->>Axys: PUT /cardholders/{cardholderId}/kyc-submit
    Axys->>You: Under Review status
    
		rect rgb(0,0,0,0.1)
    Note over You,Cardholder: Cardholder compliance submission

    Axys->>You: applicationLink for Didit KYC

    You->>Cardholder: Share applicationLink

    Cardholder->>Axys: Submit photo ID and proof of address
    Cardholder->>Axys: Complete liveness check
    end

    Axys->>Axys: Compliance review

    alt Approved
        Axys->>You: Approved status
    else Declined
        Axys->>You: Declined status
				alt Retry
    		    You->>Axys: POST /cardholders/{cardholderId}/kyc-url/refresh
		        Note over You,Cardholder: Return to Cardholder compliance submission flow
		    else Edit    
		        Note over You,Cardholder: Edit Cardholder before resubmitting to compliance
		    else Review    
		        Note over You,Cardholder: Request manual compliance review
		    end    
    end

Two compliance paths

Didit (default)

By default (sumsubEnabled = 0), submitting a Cardholder for review (PUT /cardholders/{cardholderId}/kyc-submit) generates an applicationLink — a hosted URL where the Cardholder completes their KYC:

  • Government-issued photo ID
  • Proof of address
  • Liveness verification

If the link expires or the Cardholder needs to retry, regenerate it with POST /cardholders/{cardholderId}/kyc-url/refresh. You can't regenerate a KYC URL when a Cardholder status = 1 (Approved), 4 (Draft) or 5 (Deleted), or 3 if there is already a valid KYC URL.

SumSub (token-based)

Setting sumsubEnabled = 1 (at creation via POST /cardholders, or via update before review begins) switches the Cardholder to a SumSub-based compliance flow, which requires a SumSub authentication token rather than the Didit applicationLink.

🚧

Enabling SumSub for a Program requires a specific onboarding and compliance framework. The SumSub flow's endpoints and token exchange sit alongside the sumsubEnabled flag described here. If your Program is authorized for SumSub, you will be provided with the token-exchange process at the time of onboarding. Further assistance is available via the support channels.

KYC documents

As part of the compliance process, the platform tracks the documents submitted by the Cardholder:

FieldTypeDescription
kycDocIDintegerUnique ID for this document record
statusintegerDocument-level review status
docTypeintegerDocument type (e.g. passport, national ID, proof of address)
langstringDocument language
numberstringDocument number
issueBystringIssuing authority
issuerDatestringIssue date
expireDatestringExpiry date
image_FrontExtstringFile extension of the front-side image
image_BackExtstringFile extension of the back-side image

This array is returned as kycDocs on GET /cardholders/{cardholderId}.

🚧

The KYC documents and liveness test submitted through Didit are part of an automated biometric compliance flow and they are not returned in this array by default — the array will return empty. The platform assumes that the API User should not have access to retrieve and retain such personally identifiable information. Each Program should make its own arrangements for retaining their Cardholders' KYC documents, if they intend (and are authorized) to do so.

Field-lock rules

Once a Cardholder enters status = 3 (Under Review) or status = 1 (Approved), a large set of compliance-relevant fields become permanently locked — they cannot be changed via PUT /cardholders/{cardholderId}/update, even after returning to a non-approved state. Double-check these before submitting for review:

🔒 Locked once Under Review or Approved✏️ Always editable
firstNametransactionLimit
midNamecallingCode
lastNamecountryCallingCode
genderphoneNum
nationalitycellNum
placeOfBirthemailAdr
dobadrLine2
adrLine1cardHolderFirstName
citycardHolderLastName
stateemployeeID
country
zipCode
sumsubEnabled
🚧

Every locked field above is identity or KYC-document data — the information that must match the Cardholder's government-issued ID and proof of address. Get these right in your initial POST /cardholders call; there's no path to correct a typo in, say, dob or country after submission without creating a new Cardholder record.

Cardholder Account

On creation, the platform automatically provisions the Cardholder's internal Cardholder Account — see Accounts, Wallets & Deposit Addresses. This is not a separately addressable resource.

Bank account and deposit-address registration

Approved Cardholders can register an external bank account (for bank-rail funding, with OTP verification) as a sub-resource. Digital-asset Deposit Addresses, by contrast, are generated automatically per-Card at issuance and require no registration. Both are covered in full in Funding & Deposits.

What's next



Did this page help you?