Authentication Reference
Two credential types
| Credential | Header | Lifetime | Use case |
|---|---|---|---|
| API key | X-API-Key: tcf_live_... | Until revoked | Server-to-server integrations |
| Session token | Authorization: Bearer {token} | security.session_expiry_hours (default 24h) | Client portal SPA |
API key header
http
X-API-Key: tcf_live_32randomcharactershereOn each request, TokenCashFlow:
- Hashes the provided key with SHA-256
- Looks up the hash in the
api_keystable - If found and
status = active: processes the request in the context of the key's owner - Updates
api_keys.last_used_at
Session token header
http
Authorization: Bearer eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9...Session tokens are issued on login via POST /v1/auth/login. They are opaque tokens stored in the database — not JWTs — and are invalidated server-side on logout or expiry.
Error responses
| Scenario | HTTP Status | Error code |
|---|---|---|
| No credential provided | 401 | UNAUTHORIZED |
| Invalid / revoked key | 401 | UNAUTHORIZED |
| Valid credential but insufficient permissions | 403 | FORBIDDEN |
| Valid credential but KYC not approved | 403 | KYC_REQUIRED |
Example 401 response:
json
{
"success": false,
"data": null,
"error": {
"code": "UNAUTHORIZED",
"message": "Authentication required.",
"details": {}
}
}Example 403 KYC_REQUIRED response:
json
{
"success": false,
"data": null,
"error": {
"code": "KYC_REQUIRED",
"message": "Basic KYC approval is required for this operation.",
"details": {}
}
}KYC-gated endpoints
The following operations require at least Basic KYC:
POST /v1/payments— create a paymentPOST /v1/api-keys— create an API keyPOST /v1/withdrawals/requests— request a withdrawalGET /v1/exports— request a payment export
The following require Advanced KYC:
- Enabling auto-withdraw in payment settings

