Skip to content

Authentication

TokenCashFlow supports two credential types depending on where your code runs.

Session tokens vs. API keys

CredentialHeaderUse case
API keyX-API-Key: tcf_live_...Server-to-server integrations; long-lived; create/revoke in portal
Session tokenAuthorization: Bearer {token}Client portal SPA; issued on login; expires after inactivity

For merchant integrations, always use API keys. Session tokens are used by the TokenCashFlow client portal internally and expire after a time of inactivity (default: 24 hours).

API key authentication

Header format

X-API-Key: tcf_live_32randomcharactershere

Key lifecycle

  1. Create a key in the Client PortalDashboard → API Keys
  2. The full key is shown once at creation — copy it immediately
  3. Keys are stored as SHA-256 hashes; TokenCashFlow cannot recover the original value
  4. Revoke a key in the portal at any time — takes effect immediately
  5. Create a new key before revoking an old one to avoid downtime

Key format

tcf_live_{32 URL-safe random characters}

Total length: ~44 characters.

KYC requirement

Creating payments and generating API keys require at least Basic KYC. If your KYC has not been approved, the API returns:

json
{
  "success": false,
  "data": null,
  "error": {
    "code": "KYC_REQUIRED",
    "message": "Basic KYC approval is required for this operation.",
    "details": {}
  }
}

HTTP status: 403 Forbidden

Complete KYC in the Client Portal → Dashboard → Identity Verification.

Rate limits

ScopeDefault limitResponse on exceeded
Per API key60 requests/second429 Too Many Requests
Per user (all keys combined)60 requests/second429 Too Many Requests
Global platform1,000 requests/second429 Too Many Requests

On rate-limit hit, the response includes a Retry-After header with the number of seconds to wait.

Recommended back-off strategy:

python
import time, random

def request_with_backoff(fn, max_retries=5):
    for attempt in range(max_retries):
        response = fn()
        if response.status_code != 429:
            return response
        retry_after = int(response.headers.get("Retry-After", 1))
        jitter = random.uniform(0, 0.5)
        time.sleep(retry_after + jitter)
    raise Exception("Rate limit retries exhausted")

Security best practices

  • Never expose your API key in frontend code (JavaScript, HTML, mobile app bundles). API keys are for server-side use only.
  • Store keys as environment variables, not in source code.
  • Rotate keys immediately if you suspect compromise: create a new key, deploy it, then revoke the old one.
  • Use a separate key per environment (staging, production).
  • Monitor last_used_at in the portal to detect unexpected key usage.

TokenCashFlow Documentation