Skip to Content

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

HeaderDescriptionExampleRequired
AuthorizationBearer token containing your API key.Bearer sk_live_xxxxxxxxyes
Content-TypeContent type for POST/PUT requests.application/jsonyes (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:

EnvironmentAPI Key PrefixDescription
Testsk_test_For development and testing purposes
Livesk_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.

ScopeGrants
readAll read endpoints: retrieve and list checkouts, payments, subscriptions, charges, webhook events, and settings, plus CSV report exports.
checkouts_writeCreate and cancel checkouts and subscription checkouts; create checkout quotes.
payments_writeMove funds: capture, refund, rescue, and recover payments; charge, quote, and cancel subscriptions; update charge metadata.
settings_writeChange 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

  1. Keep keys secure: Never expose your API key in client-side code or public repositories
  2. Use environment variables: Store API keys in environment variables
  3. Rotate keys regularly: If you suspect a key has been compromised, rotate it immediately
  4. Use test mode: Always test your integration with test keys before going live

Troubleshooting

Error: Unauthorized (401)

  • Ensure the Authorization header 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_xxx or Bearer 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_scope names it
  • Create a key with the required scope in your dashboard, or use one that already has it

Start building

XO

Request Demo

Schedule a call with our team

Select a product
Arrow right

Start building
Grateful

Contact Us

We're here to help