curl --request POST \
--url https://api.platform.sandbox.dakota.xyz/customers/{customer_id}/cardholders \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-idempotency-key: <x-idempotency-key>' \
--data '
{
"person_id": "33KqV8cN2pLmR5tW7xYzA1bC3dE",
"phone": "+15555550123",
"external_id": "emp-0042"
}
'{
"id": "31TgvufZK3gDXBcA3BnSeLWiSn7",
"customer_id": "2tQRvD3xFcJ7bKpW9qNsT4hZmYr",
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com",
"phone": "+15555550123",
"status": "pending",
"open_requirements": {
"count": 0,
"types": []
},
"external_id": "emp-0042",
"created_at": 1758211200,
"updated_at": 1758211200
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#cards-capability-unavailable",
"title": "Cards Capability Unavailable",
"status": 403,
"detail": "The cards capability is not available for this customer.",
"errors": [
{
"field": "cards_tos",
"message": "Cards Terms of Service must be accepted before creating a cardholder.",
"code": "terms_acceptance"
}
]
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#cardholder-person-exists",
"title": "Cardholder Person Exists",
"status": 409,
"detail": "A person with this email already exists on this application. Send person_id 2abc123 instead.",
"person_id": "2abc123"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}Create a cardholder
Create a cardholder for the given customer, gated on the cards capability being available.
The cardholder is created synchronously and returns in pending status, then transitions to
active via a cardholder.updated webhook.
The request body is one of three shapes, chosen by which fields are present:
CreateCardholderForIndividualCustomerRequest(phone, optionalemail): for an INDIVIDUAL customer. Name is taken from the individual on the customer’s latest approved application; email too, unless the individual has none on file, in which case the requestemailis required.CreateCardholderFromPersonRequest(person_id+phone, optionalemail): for a BUSINESS customer, creates a cardholder from an existing person returned byGET /customers/{customer_id}/persons. Name comes from that person; email too, unless the person has none on file, in which case the requestemailis required.CreateCardholderForNewPersonRequest(first_name,last_name,email,phone): for a BUSINESS customer, creates a cardholder from contact details supplied directly, without an existing person to reference.
An INDIVIDUAL customer only accepts the first shape; a BUSINESS customer only accepts the
second or third; sending person_id together with first_name/last_name is ambiguous and
refused. Shared email addresses between persons are not supported: whenever a shape takes its
email from the request (a new-person request’s email, or one supplied for a person with none
on file), an email matching a person already on the application is refused with
#cardholder-person-exists rather than silently creating a second person under the same
address.
person_id is validated the same way whether it fails to parse into any application person or
the customer has no approved application at all: both are the same 400 field violation on
person_id, so a caller can never use the response to probe for another customer’s application
or persons.
curl --request POST \
--url https://api.platform.sandbox.dakota.xyz/customers/{customer_id}/cardholders \
--header 'Content-Type: application/json' \
--header 'x-api-key: <api-key>' \
--header 'x-idempotency-key: <x-idempotency-key>' \
--data '
{
"person_id": "33KqV8cN2pLmR5tW7xYzA1bC3dE",
"phone": "+15555550123",
"external_id": "emp-0042"
}
'{
"id": "31TgvufZK3gDXBcA3BnSeLWiSn7",
"customer_id": "2tQRvD3xFcJ7bKpW9qNsT4hZmYr",
"first_name": "Ada",
"last_name": "Lovelace",
"email": "ada@example.com",
"phone": "+15555550123",
"status": "pending",
"open_requirements": {
"count": 0,
"types": []
},
"external_id": "emp-0042",
"created_at": 1758211200,
"updated_at": 1758211200
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#cards-capability-unavailable",
"title": "Cards Capability Unavailable",
"status": 403,
"detail": "The cards capability is not available for this customer.",
"errors": [
{
"field": "cards_tos",
"message": "Cards Terms of Service must be accepted before creating a cardholder.",
"code": "terms_acceptance"
}
]
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#cardholder-person-exists",
"title": "Cardholder Person Exists",
"status": 409,
"detail": "A person with this email already exists on this application. Send person_id 2abc123 instead.",
"person_id": "2abc123"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}{
"type": "https://docs.dakota.xyz/api-reference/errors#not-found",
"title": "Customer Not Found",
"status": 404,
"detail": "Customer cst_2abc123 was not found in your organization.",
"instance": "https://api.platform.dakota.xyz/customers/cst_2abc123",
"request_id": "req_7f3a8b2c"
}Authorizations
Headers
Unique key to ensure request idempotency. If the same key is used within a certain time window, the original response will be returned instead of executing the request again.
Path Parameters
KSUID is a 27-character globally unique ID that combines a timestamp with a random component. Used for all entity identifiers in the Dakota platform.
27^[0-9A-Za-z]{27}$"1NFHrqBHb3cTfLVkFSGmHZqdDPi"
Body
Cardholder details
- Create Cardholder For Individual Customer Request
- Create Cardholder From Person Request
- Create Cardholder For New Person Request
Creates a cardholder for an INDIVIDUAL customer. Name is not supplied here -- it is taken from the individual on the customer's latest approved onboarding application. email follows the same on-file rule as CreateCardholderFromPersonRequest: required only when the person has none on file, and otherwise rejected if it disagrees with the one already there.
The cardholder's own mobile number, E.164-formatted. It is used to verify the cardholder at online checkouts that ask for 3-D Secure, so do not send a shared or placeholder number.
"+15555550123"
Required only when the individual has no email on file. Otherwise omit it; sending a different email than the one already on file is rejected.
254"ada@example.com"
Optional client-supplied lookup key.
Cardholder's residential address. Required by the card provider; when omitted, the customer's address is used.
Show child attributes
Show child attributes
Response
Cardholder created successfully
Response containing cardholder details.
KSUID is a 27-character globally unique ID that combines a timestamp with a random component. Used for all entity identifiers in the Dakota platform.
27^[0-9A-Za-z]{27}$"1NFHrqBHb3cTfLVkFSGmHZqdDPi"
KSUID is a 27-character globally unique ID that combines a timestamp with a random component. Used for all entity identifiers in the Dakota platform.
27^[0-9A-Za-z]{27}$"1NFHrqBHb3cTfLVkFSGmHZqdDPi"
Current status of the cardholder. Returns pending on create; on the clean path it flips to active within seconds via a cardholder.updated webhook.
An enrollment flagged during screening takes a longer route: pending → under_review (a reviewer holds it) → request_for_information (the reviewer needs something from you) → active or declined. You answer information requests through the API; there is never a cardholder-facing link. Every transition emits cardholder.updated, and opening a request also emits cardholder.information_requested.
suspended and closed are lifecycle rather than review states. closed is terminal and appears only in the cardholder.updated webhook emitted when a cardholder is deleted — deleted cardholders are not returned by the REST endpoints.
pending, under_review, request_for_information, active, declined, suspended, closed "pending"
Unix timestamp (seconds) of creation.
Unix timestamp (seconds) of last update.
Summary of what a reviewer is currently waiting on for this cardholder. count is 0 and types is empty unless the cardholder is in request_for_information.
This is a summary only. Read the individual items, with their descriptions, from GET /cardholders/{cardholder_id}/application.
Show child attributes
Show child attributes
Was this page helpful?

