Skip to main content
POST
/
cardholders
Create a cardholder
curl --request POST \
  --url https://api.fyatu.com/api/v3.20/cardholders \
  --header 'Authorization: Bearer <token>' \
  --header 'Content-Type: application/json' \
  --data '
{
  "firstName": "John",
  "lastName": "Smith",
  "email": "john.smith@example.com",
  "dateOfBirth": "1990-05-15",
  "nationality": "US",
  "address": {
    "address": "123 Main Street, Apt 4B",
    "city": "Newark",
    "country": "US",
    "state": "Delaware",
    "postalCode": "19701"
  },
  "phone": "+12025551234",
  "kycDocument": {
    "documentType": "PASSPORT",
    "documentNumber": "AB123456",
    "issuingCountry": "US",
    "frontUrl": "https://storage.example.com/doc-front.jpg",
    "backUrl": null,
    "selfieUrl": "https://storage.example.com/selfie.jpg"
  },
  "externalId": "usr_123456",
  "metadata": {
    "plan": "premium"
  }
}
'
{
  "success": true,
  "status": 201,
  "message": "Cardholder created",
  "data": {
    "cardholderId": "chl_01HXYZ1234ABCDEF5678",
    "firstName": "John",
    "lastName": "Smith",
    "email": "john.smith@example.com",
    "phone": "+12025551234",
    "dateOfBirth": "1990-05-15",
    "nationality": "US",
    "address": {
      "address": "123 Main Street, Apt 4B",
      "city": "Newark",
      "state": "Delaware",
      "postalCode": "19701",
      "country": "US"
    },
    "kycDocument": null,
    "externalId": "usr_123456",
    "metadata": {
      "plan": "premium"
    },
    "status": "ACTIVE",
    "kycStatus": "PENDING",
    "kycVerifiedAt": null,
    "totalCards": 0,
    "suspendedAt": null,
    "createdAt": "2026-05-01T09:00:00Z",
    "updatedAt": "2026-05-01T09:00:00Z"
  },
  "meta": {
    "requestId": "req_a1b2c3d4e5f6a7b8c9d0e1f2",
    "platform": "Fyatu CaaS",
    "timestamp": "2026-05-01T09:00:00Z"
  }
}

Overview

Create a cardholder profile for an end user. KYC is triggered automatically and runs asynchronously — subscribe to CARDHOLDER_KYC_APPROVED or CARDHOLDER_KYC_REJECTED to be notified when it completes. Cards can only be issued once kycStatus is APPROVED.

Required Fields

FieldTypeConstraint
firstNamestringLegal first name
lastNamestringLegal last name
emailstringValid email, unique within your environment
dateOfBirthstringYYYY-MM-DD format, cardholder must be 18+
nationalitystringISO 3166-1 alpha-2 (e.g. US)
address.addressstringFull street address (line 1 and optional line 2 combined)
address.citystringCity
address.countrystringISO 3166-1 alpha-2

KYC-Locked Fields

After KYC approval, these fields become immutable: firstName, lastName, email, dateOfBirth, nationality, address. Attempting to change them returns 409 KYC_FIELD_LOCKED.

KYC Document

The optional kycDocument object lets you supply identity document details alongside the cardholder creation. It is not KYC-locked and can be updated via PATCH at any time.
FieldTypeDescription
documentTypestringPASSPORT, NATIONAL_ID, DRIVERS_LICENSE, or RESIDENCE_PERMIT
documentNumberstringDocument number as printed
issuingCountrystringISO 3166-1 alpha-2
frontUrlstringURL of the document front image
backUrlstringURL of the document back image (not required for passports)
selfieUrlstringURL of the cardholder selfie

Example

curl -X POST https://api.fyatu.com/api/v3.20/cardholders \
  -H "Authorization: Bearer $FYATU_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "firstName":   "John",
    "lastName":    "Smith",
    "email":       "john.smith@example.com",
    "phone":       "+12025551234",
    "dateOfBirth": "1990-05-15",
    "nationality": "US",
    "address": {
      "address":    "123 Main Street, Apt 4B",
      "city":       "Newark",
      "state":      "Delaware",
      "postalCode": "19701",
      "country":    "US"
    },
    "kycDocument": {
      "documentType":   "PASSPORT",
      "documentNumber": "AB123456",
      "issuingCountry": "US",
      "frontUrl":       "https://storage.example.com/doc-front.jpg",
      "selfieUrl":      "https://storage.example.com/selfie.jpg"
    },
    "externalId": "usr_123456",
    "metadata":   { "plan": "premium", "region": "us-east" }
  }'

Success Response (201)

{
  "success": true,
  "status": 201,
  "message": "Cardholder created",
  "data": {
    "cardholderId":  "chl_01HXYZ1234ABCDEF5678",
    "firstName":     "John",
    "lastName":      "Smith",
    "email":         "john.smith@example.com",
    "phone":         "+12025551234",
    "dateOfBirth":   "1990-05-15",
    "nationality":   "US",
    "address": {
      "address":    "123 Main Street, Apt 4B",
      "city":       "Newark",
      "state":      "Delaware",
      "postalCode": "19701",
      "country":    "US"
    },
    "kycDocument":   null,
    "externalId":    "usr_123456",
    "metadata":      { "plan": "premium", "region": "us-east" },
    "status":        "ACTIVE",
    "kycStatus":     "PENDING",
    "kycVerifiedAt": null,
    "totalCards":    0,
    "suspendedAt":   null,
    "createdAt":     "2026-05-22T10:00:00Z",
    "updatedAt":     "2026-05-22T10:00:00Z"
  },
  "meta": {
    "requestId": "req_01HXY123456ABCDEF",
    "platform": "Fyatu CaaS",
    "timestamp": "2026-05-22T10:00:00Z"
  }
}
Conditional fields — present only in specific states:
FieldCondition
kycRejectionReasonOnly when kycStatus is REJECTED
terminatedAtOnly when status is TERMINATED

Webhook

A CARDHOLDER_CREATED event fires after successful creation. A few seconds later in SANDBOX (async in LIVE), one of these fires:
{
  "event":      "CARDHOLDER_KYC_APPROVED",
  "eventId":    "evt_01HXY123456ABCDEF",
  "businessId": "BUS1A2B3C4D5E6F",
  "environment": "LIVE",
  "timestamp":  "2026-05-22T10:00:05Z",
  "data": {
    "cardholderId":  "chl_01HXYZ1234ABCDEF5678",
    "kycStatus":     "APPROVED",
    "kycVerifiedAt": "2026-05-22T10:00:05Z"
  }
}

Error Codes

CodeHTTPCause
INVALID_BODY400Request body is not valid JSON
VALIDATION_ERROR422Missing or invalid fields (e.g. bad email, missing address.city)
CARDHOLDER_UNDER_AGE422dateOfBirth indicates cardholder is under 18
CARDHOLDER_EMAIL_EXISTS409Email already registered in this environment
PROGRAM_NOT_FOUND404No active program found for your account
PROGRAM_CLOSED409Program is closed and cannot accept new cardholders
INSUFFICIENT_SCOPE403Key lacks cardholders:write scope
INTERNAL_ERROR500Server error

Authorizations

Authorization
string
header
required

API key from the FYATU CaaS portal. Pass as Authorization: Bearer <key>.

Body

application/json
firstName
string
required
Example:

"John"

lastName
string
required
Example:

"Smith"

email
string<email>
required
Example:

"john.smith@example.com"

dateOfBirth
string<date>
required

YYYY-MM-DD — must be 18+

Example:

"1990-05-15"

nationality
string
required

ISO 3166-1 alpha-2

Example:

"US"

address
object
required
phone
string
Example:

"+12025551234"

kycDocument
object

Identity document details for KYC verification. Optional on create; patchable via PATCH. Not locked after KYC approval.

externalId
string
Example:

"usr_123456"

metadata
object
Example:
{ "plan": "premium" }

Response

Cardholder created

success
boolean
Example:

true

status
integer
Example:

200

message
string
Example:

"Cardholder retrieved"

data
object
meta
object