Authentication
Every request is authenticated with an API key that identifies your organization, its mode, and its scopes.
The API authenticates with API keys. A key belongs to exactly one organization; every request you make with it is automatically scoped to that organization's data. There are no separate account IDs to pass — the key is the identity.
Passing the key
Send the key in the X-API-Key header:
curl https://api.caiboglobal.com/v1/organization \
-H "X-API-Key: ck_live_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"A Bearer token also works, if that fits your HTTP client better:
curl https://api.caiboglobal.com/v1/organization \
-H "Authorization: Bearer ck_live_a1b2c3d4e5f6a7b8c9d0e1f2a3b4c5d6"A missing key returns 401 authentication_error with code api_key_missing; an unknown or revoked key returns code api_key_invalid. See Errors.
Key format & modes
A key encodes its mode in the prefix. The rest of the key is a random secret; only a short prefix is ever shown again after creation.
| Prefix | Mode | What it does |
|---|---|---|
ck_test_ | Test (sandbox) | Full simulation. Never touches the blockchain. Available immediately. |
ck_live_ | Live | Moves real funds. Requires a verified business (KYB). |
Test and live are fully separate: a payout created with a test key never appears under a live key, and vice-versa. Build against test, then switch to a live key when you go to production. See Environments.
Scopes
Each key carries a set of scopes. An endpoint checks for the scope it needs and returns 403 permission_error (code scope_insufficient) if the key lacks it. Grant a key only the scopes it needs.
| Scope | Grants |
|---|---|
payouts:write | Create and cancel payouts. |
payouts:read | Retrieve and list payouts. |
balances:read | Read balances and rates. |
webhooks:write | Create and delete webhook endpoints. |
webhooks:read | List webhook endpoints. |
organization:read | Read organization and KYB status. |
organization:write | Submit KYB and manage API keys. |
Creating and rotating keys
Create keys from the Business dashboard or via POST /v1/api-keys. The full secret is returned once at creation — store it in your secret manager immediately. Listing keys only ever returns the prefix, never the secret.
Rotate keys periodically and whenever a team member with access leaves. To rotate with zero downtime:
- Create a new key with the same scopes.
- Deploy it to your backend.
- Confirm traffic is using the new key (check
last_used_at). - Revoke the old key.
Revoking is immediate — a revoked key is rejected on the very next request.
Keeping keys safe
- Backend only. API keys must never reach a browser, mobile app, or any client the user controls. A leaked live key can move money.
- Never commit keys. Keep them out of source control; load them from environment variables or a secret manager.
- Least privilege. Give each key the minimum scopes it needs.
- Separate keys per service. So you can rotate or revoke one without disrupting others.
If a key is leaked
Act immediately:
- Revoke the key (dashboard or
DELETE /v1/api-keys/{id}). This stops it working instantly. - Create a replacement and deploy it.
- Review recent activity — list recent payouts to confirm nothing unexpected was created.
The panel that manages keys, KYB, payouts, and webhooks runs on Firebase-authenticated sessions — it does not use API keys in the browser. API keys are exclusively for your server-to-server integration.