Authorization
All API requests require authentication using your API key. This page explains how to properly authorize your requests.
API Key
You need to include your API key in the Authorization header of every request using Bearer token authentication.
Your API key can be found in your dashboard settings. Keep it secure and never expose it in client-side code.
Headers
| Header | Description | Example | Required |
|---|---|---|---|
| Authorization | Bearer token containing your API key. | Bearer sk_live_xxxxxxxx | yes |
| Content-Type | Content type for POST/PUT requests. | application/json | yes (for POST/PUT) |
Example Request
Here’s a complete example showing how to authenticate:
const response = await fetch('https://checkout-api.exodus-int.com/checkouts', {
method: 'POST',
headers: {
Authorization: 'Bearer sk_live_xxxxxxxxxxxxxxxx',
'Content-Type': 'application/json',
},
body: JSON.stringify({
// Request body
}),
});Environment
The API supports two environments:
| Environment | API Key Prefix | Description |
|---|---|---|
| Test | sk_test_ | For development and testing purposes |
| Live | sk_live_ | For production transactions |
Important: Test mode API keys will not process real payments. Always use live keys in production.
Scopes
Every API key carries a set of scopes, and every endpoint requires one of them. New keys get all four scopes unless you restrict them; when creating a key in your dashboard, grant only the scopes the integration needs.
| Scope | Grants |
|---|---|
read | All read endpoints: retrieve and list checkouts, payments, subscriptions, charges, webhook events, and settings, plus CSV report exports. |
checkouts_write | Create and cancel checkouts and subscription checkouts; create checkout quotes. |
payments_write | Move funds: capture, refund, rescue, and recover payments; charge, quote, and cancel subscriptions; update charge metadata. |
settings_write | Change merchant settings: webhook URL and display name, settlement addresses, signer registration, webhook secret rotation and test sends. |
A request made with a key that lacks the required scope is rejected with 403 and error.type: "permission_error", error.code: "insufficient_scope"; error.data.required_scope names the scope the key is missing.
Scopes are additive, and write scopes do not imply read. A key restricted to
payments_write cannot list payments — grant read alongside it if the integration also fetches
payment objects.
Key Expiry
Keys can carry an optional expiry, set when the key is created in your dashboard. Requests made with an expired key are rejected with 401 and the message API key expired — the same status as an invalid key, so handle both by rotating to a fresh key.
Best Practices
- Keep keys secure: Never expose your API key in client-side code or public repositories
- Use environment variables: Store API keys in environment variables
- Rotate keys regularly: If you suspect a key has been compromised, rotate it immediately
- Use test mode: Always test your integration with test keys before going live
Troubleshooting
Error: Unauthorized (401)
- Ensure the
Authorizationheader is present - Verify the API key is valid and not expired
- Check that you’re using the correct key for the environment (test vs live)
Error: Invalid API Key
- Confirm the key format is correct:
Bearer sk_live_xxxorBearer sk_test_xxx - Ensure there are no extra spaces or characters
Error: Forbidden (403, insufficient_scope)
- The key is valid but missing the scope the endpoint requires;
error.data.required_scopenames it - Create a key with the required scope in your dashboard, or use one that already has it
