Update a cardholder
curl --request PATCH \
--url https://api.fyatu.com/api/v3.20/cardholders/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"firstName": "<string>",
"lastName": "<string>",
"email": "jsmith@example.com",
"phone": "<string>",
"dateOfBirth": "2023-12-25",
"nationality": "<string>",
"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": "<string>",
"metadata": {}
}
'import requests
url = "https://api.fyatu.com/api/v3.20/cardholders/{id}"
payload = {
"firstName": "<string>",
"lastName": "<string>",
"email": "jsmith@example.com",
"phone": "<string>",
"dateOfBirth": "2023-12-25",
"nationality": "<string>",
"kycDocument": {
"documentType": "PASSPORT",
"documentNumber": "AB123456",
"issuingCountry": "US",
"frontUrl": "https://storage.example.com/doc-front.jpg",
"backUrl": None,
"selfieUrl": "https://storage.example.com/selfie.jpg"
},
"externalId": "<string>",
"metadata": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
firstName: '<string>',
lastName: '<string>',
email: 'jsmith@example.com',
phone: '<string>',
dateOfBirth: '2023-12-25',
nationality: '<string>',
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: '<string>',
metadata: {}
})
};
fetch('https://api.fyatu.com/api/v3.20/cardholders/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fyatu.com/api/v3.20/cardholders/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'firstName' => '<string>',
'lastName' => '<string>',
'email' => 'jsmith@example.com',
'phone' => '<string>',
'dateOfBirth' => '2023-12-25',
'nationality' => '<string>',
'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' => '<string>',
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fyatu.com/api/v3.20/cardholders/{id}"
payload := strings.NewReader("{\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"nationality\": \"<string>\",\n \"kycDocument\": {\n \"documentType\": \"PASSPORT\",\n \"documentNumber\": \"AB123456\",\n \"issuingCountry\": \"US\",\n \"frontUrl\": \"https://storage.example.com/doc-front.jpg\",\n \"backUrl\": null,\n \"selfieUrl\": \"https://storage.example.com/selfie.jpg\"\n },\n \"externalId\": \"<string>\",\n \"metadata\": {}\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.fyatu.com/api/v3.20/cardholders/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"nationality\": \"<string>\",\n \"kycDocument\": {\n \"documentType\": \"PASSPORT\",\n \"documentNumber\": \"AB123456\",\n \"issuingCountry\": \"US\",\n \"frontUrl\": \"https://storage.example.com/doc-front.jpg\",\n \"backUrl\": null,\n \"selfieUrl\": \"https://storage.example.com/selfie.jpg\"\n },\n \"externalId\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fyatu.com/api/v3.20/cardholders/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"nationality\": \"<string>\",\n \"kycDocument\": {\n \"documentType\": \"PASSPORT\",\n \"documentNumber\": \"AB123456\",\n \"issuingCountry\": \"US\",\n \"frontUrl\": \"https://storage.example.com/doc-front.jpg\",\n \"backUrl\": null,\n \"selfieUrl\": \"https://storage.example.com/selfie.jpg\"\n },\n \"externalId\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": 200,
"message": "Cardholder retrieved",
"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",
"country": "US",
"state": "Delaware",
"postalCode": "19701"
},
"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"
},
"status": "ACTIVE",
"kycStatus": "APPROVED",
"kycVerifiedAt": "2026-05-10T14:23:00Z",
"kycRejectionReason": null,
"totalCards": 2,
"suspendedAt": null,
"terminatedAt": null,
"createdAt": "2026-05-01T09:00:00Z",
"updatedAt": "2026-05-10T14:23:00Z"
},
"meta": {
"requestId": "req_a1b2c3d4e5f6a7b8c9d0e1f2",
"platform": "Fyatu CaaS",
"timestamp": "2026-05-22T15:00:00Z"
}
}Cardholders
Update Cardholder
Update a cardholder’s profile fields. PATCH /cardholders/. Requires cardholders:write scope.
PATCH
/
cardholders
/
{id}
Update a cardholder
curl --request PATCH \
--url https://api.fyatu.com/api/v3.20/cardholders/{id} \
--header 'Authorization: Bearer <token>' \
--header 'Content-Type: application/json' \
--data '
{
"firstName": "<string>",
"lastName": "<string>",
"email": "jsmith@example.com",
"phone": "<string>",
"dateOfBirth": "2023-12-25",
"nationality": "<string>",
"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": "<string>",
"metadata": {}
}
'import requests
url = "https://api.fyatu.com/api/v3.20/cardholders/{id}"
payload = {
"firstName": "<string>",
"lastName": "<string>",
"email": "jsmith@example.com",
"phone": "<string>",
"dateOfBirth": "2023-12-25",
"nationality": "<string>",
"kycDocument": {
"documentType": "PASSPORT",
"documentNumber": "AB123456",
"issuingCountry": "US",
"frontUrl": "https://storage.example.com/doc-front.jpg",
"backUrl": None,
"selfieUrl": "https://storage.example.com/selfie.jpg"
},
"externalId": "<string>",
"metadata": {}
}
headers = {
"Authorization": "Bearer <token>",
"Content-Type": "application/json"
}
response = requests.patch(url, json=payload, headers=headers)
print(response.text)const options = {
method: 'PATCH',
headers: {Authorization: 'Bearer <token>', 'Content-Type': 'application/json'},
body: JSON.stringify({
firstName: '<string>',
lastName: '<string>',
email: 'jsmith@example.com',
phone: '<string>',
dateOfBirth: '2023-12-25',
nationality: '<string>',
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: '<string>',
metadata: {}
})
};
fetch('https://api.fyatu.com/api/v3.20/cardholders/{id}', options)
.then(res => res.json())
.then(res => console.log(res))
.catch(err => console.error(err));<?php
$curl = curl_init();
curl_setopt_array($curl, [
CURLOPT_URL => "https://api.fyatu.com/api/v3.20/cardholders/{id}",
CURLOPT_RETURNTRANSFER => true,
CURLOPT_ENCODING => "",
CURLOPT_MAXREDIRS => 10,
CURLOPT_TIMEOUT => 30,
CURLOPT_HTTP_VERSION => CURL_HTTP_VERSION_1_1,
CURLOPT_CUSTOMREQUEST => "PATCH",
CURLOPT_POSTFIELDS => json_encode([
'firstName' => '<string>',
'lastName' => '<string>',
'email' => 'jsmith@example.com',
'phone' => '<string>',
'dateOfBirth' => '2023-12-25',
'nationality' => '<string>',
'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' => '<string>',
'metadata' => [
]
]),
CURLOPT_HTTPHEADER => [
"Authorization: Bearer <token>",
"Content-Type: application/json"
],
]);
$response = curl_exec($curl);
$err = curl_error($curl);
curl_close($curl);
if ($err) {
echo "cURL Error #:" . $err;
} else {
echo $response;
}package main
import (
"fmt"
"strings"
"net/http"
"io"
)
func main() {
url := "https://api.fyatu.com/api/v3.20/cardholders/{id}"
payload := strings.NewReader("{\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"nationality\": \"<string>\",\n \"kycDocument\": {\n \"documentType\": \"PASSPORT\",\n \"documentNumber\": \"AB123456\",\n \"issuingCountry\": \"US\",\n \"frontUrl\": \"https://storage.example.com/doc-front.jpg\",\n \"backUrl\": null,\n \"selfieUrl\": \"https://storage.example.com/selfie.jpg\"\n },\n \"externalId\": \"<string>\",\n \"metadata\": {}\n}")
req, _ := http.NewRequest("PATCH", url, payload)
req.Header.Add("Authorization", "Bearer <token>")
req.Header.Add("Content-Type", "application/json")
res, _ := http.DefaultClient.Do(req)
defer res.Body.Close()
body, _ := io.ReadAll(res.Body)
fmt.Println(string(body))
}HttpResponse<String> response = Unirest.patch("https://api.fyatu.com/api/v3.20/cardholders/{id}")
.header("Authorization", "Bearer <token>")
.header("Content-Type", "application/json")
.body("{\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"nationality\": \"<string>\",\n \"kycDocument\": {\n \"documentType\": \"PASSPORT\",\n \"documentNumber\": \"AB123456\",\n \"issuingCountry\": \"US\",\n \"frontUrl\": \"https://storage.example.com/doc-front.jpg\",\n \"backUrl\": null,\n \"selfieUrl\": \"https://storage.example.com/selfie.jpg\"\n },\n \"externalId\": \"<string>\",\n \"metadata\": {}\n}")
.asString();require 'uri'
require 'net/http'
url = URI("https://api.fyatu.com/api/v3.20/cardholders/{id}")
http = Net::HTTP.new(url.host, url.port)
http.use_ssl = true
request = Net::HTTP::Patch.new(url)
request["Authorization"] = 'Bearer <token>'
request["Content-Type"] = 'application/json'
request.body = "{\n \"firstName\": \"<string>\",\n \"lastName\": \"<string>\",\n \"email\": \"jsmith@example.com\",\n \"phone\": \"<string>\",\n \"dateOfBirth\": \"2023-12-25\",\n \"nationality\": \"<string>\",\n \"kycDocument\": {\n \"documentType\": \"PASSPORT\",\n \"documentNumber\": \"AB123456\",\n \"issuingCountry\": \"US\",\n \"frontUrl\": \"https://storage.example.com/doc-front.jpg\",\n \"backUrl\": null,\n \"selfieUrl\": \"https://storage.example.com/selfie.jpg\"\n },\n \"externalId\": \"<string>\",\n \"metadata\": {}\n}"
response = http.request(request)
puts response.read_body{
"success": true,
"status": 200,
"message": "Cardholder retrieved",
"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",
"country": "US",
"state": "Delaware",
"postalCode": "19701"
},
"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"
},
"status": "ACTIVE",
"kycStatus": "APPROVED",
"kycVerifiedAt": "2026-05-10T14:23:00Z",
"kycRejectionReason": null,
"totalCards": 2,
"suspendedAt": null,
"terminatedAt": null,
"createdAt": "2026-05-01T09:00:00Z",
"updatedAt": "2026-05-10T14:23:00Z"
},
"meta": {
"requestId": "req_a1b2c3d4e5f6a7b8c9d0e1f2",
"platform": "Fyatu CaaS",
"timestamp": "2026-05-22T15:00:00Z"
}
}Overview
Update one or more fields on a cardholder profile. Only the fields you include in the request body are changed — absent fields are left unchanged (true PATCH semantics).KYC-Locked Fields
AfterkycStatus becomes APPROVED, the following fields are immutable:
| Locked Field | Error if changed |
|---|---|
firstName | 409 KYC_FIELD_LOCKED |
lastName | 409 KYC_FIELD_LOCKED |
email | 409 KYC_FIELD_LOCKED |
dateOfBirth | 409 KYC_FIELD_LOCKED |
nationality | 409 KYC_FIELD_LOCKED |
address | 409 KYC_FIELD_LOCKED |
phone, externalId, and metadata can be updated at any time regardless of KYC status.
Updatable Fields
| Field | Type | Constraint |
|---|---|---|
firstName | string | KYC-locked after approval |
middleName | string | Max 15 chars. Editable even after KYC approval. Send "" to clear it. Forwarded to the card network on the next card creation to distinguish holders with identical first + last names. |
lastName | string | KYC-locked after approval |
email | string | Valid email, unique in environment; KYC-locked after approval |
phone | string | E.164 format (e.g. +12025551234) |
dateOfBirth | string | YYYY-MM-DD; KYC-locked after approval |
nationality | string | ISO 3166-1 alpha-2; KYC-locked after approval |
address | object | Full address object; KYC-locked after approval |
externalId | string | Your internal user ID |
metadata | object | Arbitrary key/value pairs (max 4096 bytes) |
Example
curl -X PATCH https://api.fyatu.com/api/v3.20/cardholders/chl_01HXYZ1234ABCDEF5678 \
-H "Authorization: Bearer $FYATU_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"phone": "+12025559999",
"metadata": { "plan": "enterprise", "region": "us-east" }
}'
const resp = await fetch(
'https://api.fyatu.com/api/v3.20/cardholders/chl_01HXYZ1234ABCDEF5678',
{
method: 'PATCH',
headers: {
'Authorization': `Bearer ${process.env.FYATU_API_KEY}`,
'Content-Type': 'application/json'
},
body: JSON.stringify({
phone: '+12025559999',
metadata: { plan: 'enterprise' }
})
}
);
const body = await resp.json();
console.log('Updated:', body.data.updatedAt);
import os, requests
resp = requests.patch(
'https://api.fyatu.com/api/v3.20/cardholders/chl_01HXYZ1234ABCDEF5678',
headers={'Authorization': f'Bearer {os.environ["FYATU_API_KEY"]}'},
json={
'phone': '+12025559999',
'metadata': {'plan': 'enterprise'}
}
)
cardholder = resp.json()['data']
print('Updated at:', cardholder['updatedAt'])
Success Response (200)
Returns the full updated cardholder object:{
"success": true,
"status": 200,
"message": "Cardholder updated",
"data": {
"cardholderId": "chl_01HXYZ1234ABCDEF5678",
"programId": "prg_01HXYZ9876ABCDEF0000",
"firstName": "John",
"lastName": "Smith",
"email": "john.smith@example.com",
"phone": "+12025559999",
"dateOfBirth": "1990-05-15",
"nationality": "US",
"address": {
"line1": "123 Main Street",
"line2": "Apt 4B",
"city": "Newark",
"state": "Delaware",
"postalCode": "19701",
"country": "US"
},
"metadata": { "plan": "enterprise", "region": "us-east" },
"status": "ACTIVE",
"kycStatus": "APPROVED",
"kycVerifiedAt": "2026-05-01T09:05:00Z",
"totalCards": 2,
"totalSpendCents": 125000,
"suspendedAt": null,
"createdAt": "2026-05-01T09:00:00Z",
"updatedAt": "2026-05-22T10:00:00Z"
},
"meta": {
"requestId": "req_01HXY123456ABCDEF",
"platform": "Fyatu CaaS",
"timestamp": "2026-05-22T10:00:00Z"
}
}
Error Codes
| Code | HTTP | Cause |
|---|---|---|
VALIDATION_ERROR | 422 | Invalid field values (bad email format, metadata too large, etc.) |
CARDHOLDER_NOT_FOUND | 404 | Cardholder does not exist or belongs to another business |
CARDHOLDER_TERMINATED | 409 | Terminated cardholder cannot be modified |
KYC_FIELD_LOCKED | 409 | Attempted to change a field that is locked after KYC approval |
CARDHOLDER_EMAIL_EXISTS | 409 | Updated email is already in use by another cardholder |
INSUFFICIENT_SCOPE | 403 | Key lacks cardholders:write scope |
Authorizations
API key from the FYATU CaaS portal. Pass as Authorization: Bearer <key>.
Path Parameters
Body
application/json
Show child attributes
Show child attributes
Identity document details for KYC verification. Optional on create; patchable via PATCH. Not locked after KYC approval.
Show child attributes
Show child attributes
⌘I

