Skip to content

Cardholders

Cardholders are managed users your business creates and controls. You can issue physical or virtual cards to them, fund their wallets, and monitor spending — all programmatically.

Full Lifecycle

1. Create cardholder
2. Complete KYC (via SumSub token)
3. Issue a card
4. Fund the cardholder's wallet
5. Manage card — freeze/unfreeze, set limits, view secrets
6. Monitor transactions
7. Recall unused funds

Cardholder Object

json
{
  "id": "uuid",
  "business_id": "uuid",
  "name": "Bob Jones",
  "email": "bob@yourcompany.com",
  "username": "bob_abc123",
  "is_kyc_verified": false,
  "created_at": "2026-03-16T10:00:00Z"
}

Card Object

json
{
  "id": "uuid",
  "user_id": "uuid",
  "catalogue_id": "uuid",
  "status": "active",
  "ctype": "virtual",
  "last4": "4242",
  "exp_month": "03",
  "exp_year": "2029",
  "spend_tx_max": 100000,
  "spend_daily_max": 500000,
  "spend_monthly_max": 2000000,
  "spend_online_enabled": true,
  "spend_present_enabled": false,
  "created_at": "2026-03-16T10:00:00Z"
}

Card status values: notActivated | active | locked | canceled


Step 1 — Create Cardholder

http
POST /v1/cardholders

Body

FieldTypeRequiredDescription
namestringFull name
emailstringEmail address

Example

bash
curl -X POST https://api-test.dpt.xyz/v1/cardholders \
  -H "Authorization: Bearer dptb_..." \
  -H "Content-Type: application/json" \
  -d '{ "name": "Bob Jones", "email": "bob@yourcompany.com" }'

Response 200

Returns the Cardholder object. Note the id — you will need it for all subsequent calls.


Step 2 — Start KYC

Returns a SumSub SDK token. Embed the SumSub Web SDK in your app and pass the token to collect the cardholder's identity documents.

http
POST /v1/cardholders/{id}/kyc

Response 200

json
{ "token": "sumsub_sdk_token_..." }

After the cardholder completes verification, is_kyc_verified becomes true. KYC status is updated automatically via webhook from SumSub — no polling needed.


Step 3 — Issue a Card

The cardholder must be KYC-verified before a card can be issued.

http
POST /v1/cardholders/{id}/cards

Body

FieldTypeRequiredDescription
catalogueuuidCard product ID (get from dashboard)
typestringvirtual or physical

Example

bash
curl -X POST https://api-test.dpt.xyz/v1/cardholders/CH_ID/cards \
  -H "Authorization: Bearer dptb_..." \
  -H "Content-Type: application/json" \
  -d '{ "catalogue": "CATALOGUE_UUID", "type": "virtual" }'

Step 4 — Fund Cardholder

Transfer funds from your business wallet to the cardholder's wallet.

http
POST /v1/cardholders/{id}/fund

Body

FieldTypeRequiredDescription
amountintegerAmount in smallest unit
currencystringe.g. USDC
remarkstringOptional memo

Example

bash
curl -X POST https://api-test.dpt.xyz/v1/cardholders/CH_ID/fund \
  -H "Authorization: Bearer dptb_..." \
  -H "Content-Type: application/json" \
  -d '{ "amount": 1000000000, "currency": "USDC" }'

Returns 204 No Content.


List Cardholders

http
GET /v1/cardholders

Get Cardholder

http
GET /v1/cardholders/{id}

Recall Funds

Pull unused funds back from a cardholder's wallet to your business wallet.

http
POST /v1/cardholders/{id}/recall

Same body as Fund Cardholder. Returns 204 No Content.


List Cardholder Cards

http
GET /v1/cardholders/{id}/cards

Get Card

http
GET /v1/cardholders/{ch_id}/cards/{card_id}

Update Card (Freeze / Unfreeze)

http
PATCH /v1/cardholders/{ch_id}/cards/{card_id}

Body

FieldTypeRequiredDescription
statusstringactive to unfreeze, locked to freeze

Update Card Spending Limits

http
PUT /v1/cardholders/{ch_id}/cards/{card_id}/limits

Body

FieldTypeDescription
spend_tx_maxintegerMax per-transaction amount (cents/micro-units)
spend_daily_maxintegerMax daily spend
spend_monthly_maxintegerMax monthly spend
spend_online_enabledboolAllow online / card-not-present transactions
spend_present_enabledboolAllow in-person / contactless transactions

Get Card Secrets (PAN + CVV)

Returns the full card number and CVV, encrypted with Rain's public key. You must use the Rain Secure SDK to decrypt and display these to the cardholder.

http
POST /v1/cardholders/{ch_id}/cards/{card_id}/secrets

Body

FieldTypeRequiredDescription
sessionstringSession token from Rain Secure SDK
encrypted_dataobjectAdditional encrypted payload if required

Response 200

json
{
  "encryptedCvc": { "iv": "...", "data": "..." },
  "encryptedPan": { "iv": "...", "data": "..." }
}

Get Card PIN

http
GET /v1/cardholders/{ch_id}/cards/{card_id}/pin

Same request body as Get Secrets.

Response 200

json
{
  "encryptedPin": { "iv": "...", "data": "..." }
}

Set Card PIN

http
PUT /v1/cardholders/{ch_id}/cards/{card_id}/pin

Body

FieldTypeRequiredDescription
sessionstringSession token from Rain Secure SDK
encrypted_dataobjectNew PIN encrypted with Rain's public key

Returns 200 OK.


List Card Transactions

http
GET /v1/cardholders/{ch_id}/cards/{card_id}/transactions

Returns the most recent card transactions for this card.

Response 200

json
[
  {
    "id": "uuid",
    "amount": -50000,
    "currency": "USDC",
    "description": "Starbucks #1234",
    "status": "completed",
    "created_at": "2026-03-16T09:00:00Z"
  }
]

DPT Merchant API