Every request to the Crypto Checkout public API (/api/v1/*) must include a valid API key as a Bearer token in the Authorization header. There are no session cookies, no OAuth flows, and no IP allowlists — the key is the sole credential. Requests that are missing a key, present an invalid key, or use a key that lacks the required scope are rejected before any business logic runs.
Getting an API key
- Sign in to your dashboard and go to Dashboard → API Keys (or navigate directly to
/dashboard/api-keys).
- Click Create key.
- Give the key a name, choose a mode (test or live), and select the scopes your integration needs.
- Click Create. The raw key value is displayed exactly once — copy it immediately and store it in a secrets manager or
.env file. The dashboard stores only a SHA-256 hash of the key and can never show you the raw value again.
If you lose a key, revoke it and generate a new one.
All API keys follow the pattern ck_{mode}_{32-char-base62-string}:
| Prefix | Mode | Description |
|---|
ck_live_ | Live | Processes real payments. Guards real funds. |
ck_test_ | Test | Interacts only with test sessions. Never moves real funds. |
Passing the key in requests
Include the key in the Authorization header of every request:
Authorization: Bearer ck_live_YOUR_KEY
Example with curl:
curl https://your-domain.com/api/v1/checkout_sessions \
-H "Authorization: Bearer ck_live_YOUR_KEY"
Example with the TypeScript SDK (the key is set once at client construction and sent automatically on every request):
import { CheckoutClient } from "@your-org/checkout-sdk";
const client = new CheckoutClient({
apiKey: process.env.CHECKOUT_API_KEY!,
baseUrl: "https://your-domain.com",
});
Available scopes
Scopes follow a resource:action naming convention. Assign only the scopes your integration actually needs — a payment link webhook receiver, for example, needs no write access to sessions.
| Scope | Grants access to |
|---|
links:read | List and retrieve payment links |
links:write | Create, update, and archive payment links |
sessions:read | List and retrieve checkout sessions |
sessions:write | Create checkout sessions |
webhooks:read | List and retrieve webhook endpoints |
webhooks:write | Create, delete, and test webhook endpoints |
events:read | List and retrieve event objects |
customers:read | List and retrieve customer records |
customers:write | Create and update customer records |
Read scopes do not imply write scopes. If you need both, select both explicitly when creating the key.
Live mode vs. test mode
Test keys (ck_test_...) and live keys (ck_live_...) operate in completely separate environments:
- A test key can only read and write test-mode sessions and payment links. No funds are moved.
- A live key can only read and write live-mode objects. Payments result in real on-chain transactions.
The two environments are fully isolated — a live key cannot retrieve a test session, and vice versa. The livemode boolean on every API object indicates which environment it belongs to.
Never use a live key in a development or staging environment. Always use ck_test_ keys until you are ready for production traffic.
Authentication errors
| HTTP status | Meaning |
|---|
401 Unauthorized | The Authorization header is missing, malformed, or the key is invalid or revoked. |
403 Forbidden | The key is valid but does not have the scope required for this operation. |
Both errors return a JSON body in the standard error envelope:
{
"error": {
"type": "authentication",
"code": "invalid_api_key",
"message": "No valid API key was provided.",
"requestId": "req_01j..."
}
}
A 403 response has "type": "permission" and identifies the missing scope in the message field.
Rate limiting
Requests are rate-limited per API key. When you exceed the limit, the API returns 429 Too Many Requests. The response body follows the standard error envelope with "type": "rate_limited".
Back off and retry after a short delay. Consider using the Idempotency-Key header on mutating requests so that retries are safe — a replay within the 24-hour window returns the original response without re-executing the operation.
Security best practices
Follow these guidelines to keep your integration secure from day one.
- Keep keys secret. Never commit an API key to source control, log it, or expose it in client-side JavaScript. Use environment variables or a secrets manager.
- Use minimal scopes. Grant each key only the scopes it actually needs. A read-only reporting key should have no write scopes.
- Rotate keys regularly. Revoke old keys from the dashboard and issue new ones on a schedule, or immediately after any suspected exposure.
- Use test keys during development. Develop and test exclusively with
ck_test_ keys. Promote to live keys only in your production environment.
- Revoke unused keys promptly. Any key that is no longer in use should be revoked from Dashboard → API Keys immediately.