Documentation Index Fetch the complete documentation index at: https://docs.fyatu.com/llms.txt
Use this file to discover all available pages before exploring further.
Error Handling
The FYATU API v3.20 uses conventional HTTP response codes and returns detailed error objects with machine-readable codes to help you handle errors programmatically.
All V3.20 responses follow a consistent structure:
Success Response
Error Response
{
"success" : true ,
"status" : 200 ,
"message" : "Operation completed successfully" ,
"data" : { },
"meta" : {
"requestId" : "req_7af4d2b8e91c35fa" ,
"timestamp" : "2026-04-30T10:30:00+00:00"
}
}
Always include the requestId from the meta object when contacting support — it lets us trace your request through our systems.
HTTP Status Codes
Code Status Description 200OK Request succeeded 201Created Resource created successfully 400Bad Request Invalid request parameters or validation failed 401Unauthorized Authentication failed or token expired 402Payment Required Insufficient wallet balance 403Forbidden Token lacks required scope for this endpoint 404Not Found Resource doesn’t exist or doesn’t belong to your business 409Conflict Conflicting state (e.g., card already frozen) 422Unprocessable Entity Request understood but cannot be processed 429Too Many Requests Rate limit exceeded 500Server Error Unexpected server error on our end
Error Codes
Code HTTP Description AUTH_TOKEN_MISSING401 No Authorization header provided AUTH_TOKEN_INVALID401 Token is malformed, expired, or revoked AUTH_INVALID_CREDENTIALS401 Business ID not found or secret key mismatch AUTH_BUSINESS_INACTIVE401 Business account is suspended or inactive AUTH_SCOPE_DENIED403 Token doesn’t have the required scope for this endpoint AUTH_VERSION_MISMATCH401 Token was issued for a different API version (e.g., V3 token on V3.20 endpoint) VALIDATION_ERROR400 One or more request fields failed validation RESOURCE_NOT_FOUND404 The requested resource does not exist or belongs to another business INSUFFICIENT_BALANCE402 Wallet balance is too low for this operation PRODUCT_NOT_FOUND404 The specified productId does not exist under your program PRODUCT_INACTIVE422 The card product is currently inactive CARDHOLDER_INACTIVE422 Cardholder is not active or KYC not verified CARD_ALREADY_FROZEN409 Cannot freeze an already-frozen card CARD_NOT_FROZEN409 Cannot unfreeze a card that is not frozen RATE_LIMIT_EXCEEDED429 Too many requests — slow down INTERNAL_ERROR500 Unexpected server error
Common Error Scenarios
Authentication Errors (401)
{
"success" : false ,
"status" : 401 ,
"message" : "Authorization token is required" ,
"error" : { "code" : "AUTH_TOKEN_MISSING" }
}
Solution : Include Authorization: Bearer {token} header in every request.
{
"success" : false ,
"status" : 401 ,
"message" : "Invalid or expired token" ,
"error" : { "code" : "AUTH_TOKEN_INVALID" }
}
Solution : Refresh your token via POST /v3.20/auth/refresh or request a new one via POST /v3.20/auth/token.
{
"success" : false ,
"status" : 401 ,
"message" : "Token version mismatch. This endpoint requires a V3.20 token." ,
"error" : { "code" : "AUTH_VERSION_MISMATCH" }
}
Solution : Generate a new token via POST /v3.20/auth/token using your businessId and secretKey. V3 app tokens are not accepted on V3.20 endpoints.
Scope Errors (403)
{
"success" : false ,
"status" : 403 ,
"message" : "Access denied. Required scope: cards:write" ,
"error" : { "code" : "AUTH_SCOPE_DENIED" }
}
Solution : Request a new token that includes the required scope. You cannot add scopes to an existing token — issue a new one.
Validation Errors (400)
{
"success" : false ,
"status" : 400 ,
"message" : "Validation failed" ,
"error" : {
"code" : "VALIDATION_ERROR" ,
"details" : [
{ "field" : "productId" , "message" : "productId is required" },
{ "field" : "amount" , "message" : "Amount must be greater than 0" }
]
}
}
Solution : Check the details array for specific field requirements and correct the request payload.
Insufficient Balance (402)
{
"success" : false ,
"status" : 402 ,
"message" : "Insufficient balance. Required: $105.00, Available: $50.00" ,
"error" : { "code" : "INSUFFICIENT_BALANCE" }
}
Solution : Fund your business wallet before retrying. The required amount includes issuance fees.
Product Not Found (404)
{
"success" : false ,
"status" : 404 ,
"message" : "Card product not found" ,
"error" : { "code" : "PRODUCT_NOT_FOUND" }
}
Solution : Use GET /programs/{programId}/products to list your available products and verify the productId.
Rate Limiting (429)
{
"success" : false ,
"status" : 429 ,
"message" : "Rate limit exceeded. Try again in 60 seconds." ,
"error" : { "code" : "RATE_LIMIT_EXCEEDED" }
}
Solution : Implement exponential backoff in your retry logic.
Error Handling Best Practices
Check the Response Status
const response = await fetch ( 'https://api.fyatu.com/api/v3.20/cards' , {
method: 'POST' ,
headers: {
'Authorization' : `Bearer ${ accessToken } ` ,
'Content-Type' : 'application/json'
},
body: JSON . stringify ( cardData )
});
const result = await response . json ();
if ( ! result . success ) {
console . error ( `[ ${ result . error ?. code } ]: ${ result . message } ` );
console . error ( 'Request ID:' , result . meta ?. requestId );
return ;
}
console . log ( 'Card created:' , result . data . id );
Handle Specific Error Codes
async function createCard ( data ) {
const result = await fyatuRequest ( 'POST' , '/v3.20/cards' , data );
if ( result . success ) return { ok: true , card: result . data };
switch ( result . error ?. code ) {
case 'AUTH_TOKEN_INVALID' :
await refreshToken ();
return createCard ( data );
case 'AUTH_SCOPE_DENIED' :
return { ok: false , error: 'Token lacks cards:write scope — re-authenticate with correct scopes' };
case 'VALIDATION_ERROR' :
return { ok: false , fields: result . error . details };
case 'INSUFFICIENT_BALANCE' :
return { ok: false , error: 'Fund your wallet before issuing cards' };
case 'PRODUCT_NOT_FOUND' :
return { ok: false , error: 'Invalid productId — use GET /programs/{id}/products to list valid products' };
case 'CARDHOLDER_INACTIVE' :
return { ok: false , error: 'Cardholder KYC not verified' };
case 'RATE_LIMIT_EXCEEDED' :
await sleep ( 60000 );
return createCard ( data );
default :
return { ok: false , error: result . message };
}
}
Implement Retry with Backoff
async function requestWithRetry ( method , endpoint , data , maxRetries = 3 ) {
for ( let attempt = 1 ; attempt <= maxRetries ; attempt ++ ) {
const result = await fyatuRequest ( method , endpoint , data );
if ( result . success ) return result ;
if ( result . status === 429 || result . status >= 500 ) {
const waitMs = Math . pow ( 2 , attempt ) * 1000 ;
await new Promise ( r => setTimeout ( r , waitMs ));
continue ;
}
return result ;
}
throw new Error ( `Failed after ${ maxRetries } retries` );
}
Rate Limits
Endpoint Category Rate Limit Authentication (/v3.20/auth/*) 10 requests per minute Read endpoints (GET) 120 requests per minute Write endpoints (POST/PUT/PATCH/DELETE) 60 requests per minute
Exceeding rate limits returns 429 Too Many Requests. Implement exponential backoff in retry logic.