Skip to main content

Authentication

The FYATU CaaS API v3.20 uses API key authentication — no tokens to exchange, no JWTs to decode. Every request must include a valid API key, and the key’s scopes determine what the request is allowed to do.

How It Works

┌─────────────────────────────────────────────────────────────────────┐
│                                                                     │
│   Your server                FYATU CaaS API                        │
│                                                                     │
│   GET /cardholders  ──────────────────────────────────────────────► │
│   Authorization: Bearer fyatu_live_abc123...                        │
│                                                                     │
│                       ① Validate key (SHA-256 hash lookup)         │
│                       ② Check key status (ACTIVE / REVOKED)        │
│                       ③ Check IP allowlist (if configured)         │
│                       ④ Check business status (ACTIVE)             │
│                       ⑤ Sliding-window rate limit (1,000/min)      │
│                       ⑥ Enforce scope (cardholders:read)           │
│                                                                     │
│                ◄──────────────────────────────────────────────────  │
│   200 OK + cardholder list                                          │
│                                                                     │
└─────────────────────────────────────────────────────────────────────┘

Getting Your API Key

1

Open the CaaS portal

Go to platform.fyatu.com and log in to your CaaS account.
2

Navigate to API Keys

Click DeveloperAPI Keys in the left sidebar.
3

Create an API key

Click Create API Key. Name the key, choose its environment (LIVE or SANDBOX), and select the scopes it needs.
4

Copy the key immediately

The full key is shown once at creation time. Copy it to your secrets manager now — it cannot be retrieved later.
API keys are shown once at creation. If you lose a key, revoke it and create a new one. Never log keys or commit them to version control.

Sending the API Key

Pass your key in the Authorization header as a Bearer token. This is the only supported method.
curl -X GET https://api.fyatu.com/api/v3.20/cardholders \
  -H "Authorization: Bearer fyatu_live_abc123def456ghi789jkl012mno345pqr678stu901vwx234"

Authentication Failure Response

When authentication fails, the API returns an error using the standard response envelope:
401 — Invalid API key
{
  "success": false,
  "status": 401,
  "message": "API key is invalid or does not exist",
  "error": {
    "code": "API_KEY_INVALID",
    "detail": "The provided API key was not found in this environment"
  },
  "meta": {
    "requestId": "req_01HXY123456ABCDEF",
    "platform": "Fyatu CaaS",
    "timestamp": "2026-05-22T10:00:00Z"
  }
}
403 — Insufficient scope
{
  "success": false,
  "status": 403,
  "message": "API key does not have the required scope",
  "error": {
    "code": "INSUFFICIENT_SCOPE",
    "detail": "This endpoint requires the cards:write scope"
  },
  "meta": {
    "requestId": "req_01HXY123456ABCDEF",
    "platform": "Fyatu CaaS",
    "timestamp": "2026-05-22T10:00:00Z"
  }
}

Environment Isolation

Each API key is bound to a single environment. Keys issued for SANDBOX only work against sandbox data; LIVE keys only against live data. The environment is enforced server-side — you cannot mix data between environments and attempting to do so returns API_KEY_INVALID.
EnvironmentPurpose
SANDBOXDevelopment and testing. No real card issuance. KYC completes in seconds.
LIVEProduction. Real cardholders, real cards, real transactions.
Always build and test against SANDBOX before switching to LIVE. The two environments have separate programs, cardholders, and cards — nothing carries over.

Scopes

API keys are scoped to specific resource permissions. A key without a scope cannot call endpoints that require it — it receives a 403 INSUFFICIENT_SCOPE response. Assign only the scopes your integration actually needs.
ScopeWhat It Grants
cardholders:readGET /cardholders, GET /cardholders/{id}
cardholders:writePOST /cardholders, PATCH /cardholders/{id}, POST /cardholders/{id}/suspend, POST /cardholders/{id}/reactivate
cards:readGET /cards, GET /cards/{id}
cards:writePOST /cards, POST /cards/{id}/freeze, POST /cards/{id}/unfreeze, POST /cards/{id}/terminate, POST /cards/{id}/fund, POST /cards/{id}/unload
transactions:readGET /transactions, GET /transactions/{id}
webhooks:readGET /webhooks, GET /webhooks/{id}
webhooks:writePOST /webhooks, PATCH /webhooks/{id}, DELETE /webhooks/{id}
Create separate keys for separate services. A read-only reporting service should only have *:read scopes. A compromised minimal-scope key limits the blast radius.

Idempotency-Key Header

For write operations (POST), you can supply an Idempotency-Key header to safely retry requests without risking duplicate operations.
curl -X POST https://api.fyatu.com/api/v3.20/cards/crd_01HXYZ.../fund \
  -H "Authorization: Bearer $FYATU_API_KEY" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: fund-card-crd01HXYZ-order-9991" \
  -d '{ "amount": 50.00 }'
How it works:
  • If a request with the same Idempotency-Key is received within 24 hours, the API replays the original response without re-executing the operation.
  • Replayed responses include the header Idempotency-Replayed: true.
  • Keys must be unique strings of up to 255 characters. A UUID or a deterministic hash of your operation parameters works well.
  • After 24 hours, the key expires and a request with the same key is treated as a new operation.
# Replayed response headers
Idempotency-Replayed: true
If you send the same Idempotency-Key with a different request body, the API returns 422 IDEMPOTENCY_KEY_TOO_LONG if the key is malformed, or 409 CONFLICT if the body does not match the original request.
When to use it: Fund card, create cardholder, issue card, and any write operation that should not be duplicated if your network times out and you retry.

Rate Limits

The CaaS API enforces a sliding-window rate limit of 1,000 requests per minute per API key. Every response includes rate-limit headers:
HeaderDescription
X-RateLimit-LimitYour key’s request cap per minute
X-RateLimit-RemainingRequests remaining in the current window
X-RateLimit-ResetUnix timestamp when the window resets
When you exceed the limit, the API returns 429 RATE_LIMITED. Implement exponential backoff:
async function withBackoff(fn, maxRetries = 3) {
  for (let attempt = 0; attempt < maxRetries; attempt++) {
    const res = await fn();
    if (res.status !== 429) return res;
    const resetAt = res.headers.get('X-RateLimit-Reset');
    const wait = resetAt
      ? (Number(resetAt) * 1000 - Date.now())
      : (2 ** attempt * 1000);
    await new Promise(r => setTimeout(r, Math.max(wait, 1000)));
  }
  throw new Error('Rate limit retries exhausted');
}

IP Allowlisting

API keys can optionally restrict which IP addresses may use them. If you configure an IP allowlist in the portal and a request arrives from an unlisted IP, the API returns 403 IP_NOT_ALLOWED. This is strongly recommended for server-to-server LIVE integrations. Leave the allowlist empty during development or when your server IPs are dynamic.

Authentication Error Reference

CodeHTTPCause
API_KEY_INVALID401Key does not exist in this environment or is malformed
API_KEY_REVOKED401Key was explicitly revoked in the portal
API_KEY_EXPIRED401Key passed its expiry date
IP_NOT_ALLOWED403Client IP is not in the key’s allowlist
BUSINESS_SUSPENDED403Business account is suspended
BUSINESS_CLOSED403Business account is permanently closed
INSUFFICIENT_SCOPE403Key does not have the required scope
RATE_LIMITED429Request rate exceeded

Best Practices

Never hard-code API keys in source files. Use environment variables or a secrets manager (AWS Secrets Manager, HashiCorp Vault, Doppler, etc.). Rotate keys at least every 90 days.
Issue one key per microservice or integration, each with the minimal required scopes. This lets you revoke a single key without disrupting other services.
For production workloads, set an IP allowlist on your LIVE API keys. This adds a layer of defense even if a key is leaked — the attacker cannot use it from an unlisted IP.
Network failures happen. Always supply Idempotency-Key on fund, issue, and create requests so a retry never double-charges your program balance.
Log X-RateLimit-Remaining on every response. If it consistently approaches zero, batch requests, cache reads, or contact support to request a higher rate limit.