Skip to main content
Cardholders are the end users who receive and use cards. Each cardholder belongs to a single partner and must complete KYC before cards can be issued.

Create a cardholder

curl -X POST https://api.contro.me/v1/partner/cardholders \
  -H "x-contro-api-key: $CONTRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "externalUserId": "your_user_id",
    "firstName": "Jane",
    "lastName": "Doe",
    "email": "jane@example.com",
    "phoneNumber": "+1234567890",
    "metadata": { "plan": "premium" }
  }'

Required fields

FieldTypeDescription
externalUserIdstringYour unique identifier for this user. Min 1 character. Example: "user_42"
firstNamestringCardholder’s first name. Min 1 character. Example: "Jane"
lastNamestringCardholder’s last name. Min 1 character. Example: "Doe"
emailstringValid email address. Example: "jane@example.com"

Optional fields

FieldTypeDescription
phoneNumberstringE.164 formatted phone number. Example: "+14155552671"
metadataobjectArbitrary key-value pairs for your use. Example: { "plan": "premium", "tier": "gold" }

KYC verification

Cards cannot be issued until a cardholder’s KYC status is approved. The KYC flow has two steps:

Initiate KYC

curl -X POST https://api.contro.me/v1/partner/cardholders/{id}/kyc \
  -H "x-contro-api-key: $CONTRO_API_KEY"

Check KYC status

curl https://api.contro.me/v1/partner/cardholders/{id}/kyc \
  -H "x-contro-api-key: $CONTRO_API_KEY"
Response:
{
  "kycStatus": "approved"
}

KYC status lifecycle

StatusDescription
pendingKYC has been initiated, verification in progress
approvedVerification passed — cards can be issued
rejectedVerification failed — review and retry
In sandbox mode, KYC is auto-approved for testing. In production, verification is performed by the KYC provider.

Update a cardholder

Update mutable fields on an existing cardholder:
curl -X PATCH https://api.contro.me/v1/partner/cardholders/{id} \
  -H "x-contro-api-key: $CONTRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "email": "jane.doe@newdomain.com",
    "metadata": { "plan": "enterprise" }
  }'
Updatable fields: firstName, lastName, email, phoneNumber, metadata.

List cardholders

Retrieve cardholders with optional filtering:
curl "https://api.contro.me/v1/partner/cardholders?limit=20&status=active&kycStatus=approved" \
  -H "x-contro-api-key: $CONTRO_API_KEY"

Query parameters

ParameterTypeDescription
cursorstringPagination cursor from the previous response’s nextCursor
limitintegerItems per page (1–100, default 20). Example: 50
statusstringFilter by cardholder status. One of active, suspended, closed
kycStatusstringFilter by KYC status. One of pending, approved, rejected

Get a cardholder

Retrieve a single cardholder by ID:
curl https://api.contro.me/v1/partner/cardholders/{id} \
  -H "x-contro-api-key: $CONTRO_API_KEY"

Response fields

FieldTypeDescription
idstringContro cardholder ID. Example: "ch_abc123"
externalUserIdstringYour user identifier. Example: "user_42"
firstNamestringFirst name. Example: "Jane"
lastNamestringLast name. Example: "Doe"
emailstringEmail address. Example: "jane@example.com"
phoneNumberstring | nullE.164 phone number, or null if not provided. Example: "+14155552671"
kycStatusstringKYC verification status. One of pending, approved, rejected
statusstringCardholder account status. One of active, suspended, closed
metadataobject | nullCustom metadata, or null if not set. Example: { "plan": "premium" }
createdAtstringISO 8601 creation timestamp. Example: "2026-03-20T14:30:00Z"