Authentication
Every request is authenticated with an API key, sent as a bearer token in the
Authorization header:
Authorization: Bearer sk_live_2f6b0e4a1f9e2b1d5c7a0e3f11...
A request with a missing or invalid key is rejected with 401 authentication_error (see Errors). A secret key can move
money, so treat it like a password. Keep it on your server, out of source
control, and never ship it in a browser or mobile app.
Two kinds of key
Each account has a secret key and a publishable key.
| Key | Prefix | Use it for |
|---|---|---|
| Secret | sk_live_…, sk_test_… |
Server-side requests. It has full access to your account. |
| Publishable | pk_live_…, pk_test_… |
Identifying your account in contexts where a secret would be unsafe. It cannot authorize writes. |
You can view, copy, and roll keys in the dashboard under Settings, API keys. Rolling a key issues a new secret and stops the old one immediately, so update your servers before you roll in production.
Live and test
The environment is carried in the key itself. A live key reads and writes real
data; a test key works against a separate test environment with the same
endpoints and behavior. There is no separate host to configure. The key decides
which data you touch, which makes it easy to run the same code against test and
live.
Working inside a program
Most resources belong to a program, an isolated book of accounts. For those
endpoints, name the program in the program_id header:
program_id: prog_1U09GGBWE4mVGRnIL6GmVmeZ
Account, transaction, hold, and reconciliation endpoints require it. Account-wide endpoints (programs, webhooks, and events) do not, because they are not tied to a single set of books.
Headers at a glance
| Header | When | Purpose |
|---|---|---|
Authorization |
Always | Bearer <secret_key> |
Content-Type |
On writes | application/json |
program_id |
Program-scoped endpoints | The program the request runs against |
idempotency_key |
Recommended on writes | Retry safely without duplicating. See Idempotency. |