Get started
Authentication
One credential model for every surface. Bearer tokens, scoped access, and an environment baked into each key.
Every request authenticates with a bearer token in the Authorization header:
-H "Authorization: Bearer sk_test_XXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXXX"The token's prefix tells you — and Payer — exactly what it is, who holds it, and which environment it belongs to. Tokens are shown once at issuance, stored only as a hash, and can be rotated or revoked without downtime. Every issue, rotation and revocation lands in an audit ledger.
Credential types
| Prefix | Kind | Who holds it | What it can do |
|---|---|---|---|
pk_live_ · pk_test_ | Publishable key | A merchant, client-side | Create checkout sessions only. Safe to ship in a browser or app bundle. |
sk_live_ · sk_test_ | Secret key | A merchant, server-side | Full merchant scope, bounded by the scopes you grant. Never expose it. |
pat_ | Personal access token | An individual, on their own account | Read your own balance, transactions and insights. |
oat_ | OAuth2 access token | A third-party app, for a user | Whatever the user consented to, and nothing more. |
whsec_ | Webhook signing secret | Your endpoint | Verify that a delivery really came from Payer. |
Warning
A secret key (sk_) can move money and read everything its scopes allow. Keep it server-side, in a secret manager — never in a repo, a browser bundle, or a mobile app. If one leaks, rotate it from the dashboard immediately.
Scopes
Access is capability-based. A scope means the same thing whoever holds the credential, and a token can only reach what its scopes admit — every other field is refused, even other reads.
| Scope | Grants | Held by |
|---|---|---|
checkout:write | Create and cancel checkout sessions | pk, sk |
balances:read | Read wallet balances | sk, pat, oat |
transactions:read | Read transaction history and insights | sk, pat, oat |
wallets:read | Read wallet details | sk, pat, oat |
kyc:read | Read KYC status | sk, pat, oat |
payments:write | Move money | sk (step-up required) |
payouts:write · refunds:write | Payouts and refunds | sk |
webhooks:manage | Manage webhook endpoints | sk |
Grant a credential the least it needs. A key that only creates checkout sessions can't read a balance, and a request for a scope the key doesn't hold gets a 403 — see Errors.
Environments
The sandbox is a separate deployment with its own accounts, keys and data, running the same code path as production — so what you test is what ships. You never point at a different host to reach it.
| Environment | Key prefix | Base URL |
|---|---|---|
| Sandbox | sk_test_ · pk_test_ | https://api.payer.app |
| Production | sk_live_ · pk_live_ | https://api.payer.app |
Same URL, same request shape — swap the key to move between them. A test key can't touch production data, and a live key can't touch the sandbox. The environment is carried on the credential, so it also shows up in logs and in the dashboard.
Rate limits
Limits are per credential, so one busy integration can't throttle the rest of your account. When you exceed a limit you get a 429.
| Credential | Limit |
|---|---|
Publishable key (pk_) | 60 requests / minute |
Secret key (sk_) | 600 requests / minute |
Personal access token (pat_) | 300 requests / minute |
OAuth2 access token (oat_) | 300 requests / minute |
OAuth token endpoint (/oauth/token) | 60 requests / minute, per client |
Idempotency
Every mutating request is safe to retry. Send an Idempotency-Key header (any unique string — a UUID or your own order id) on a POST, and a repeat of the same key replays the original response instead of acting twice:
-H "Idempotency-Key: 5f4d3c2b-1a09-4e8d-b7c6-5a4b3c2d1e0f"- The same key with the same body replays the stored response, tagged
Idempotent-Replay: true. - The same key with a different body is rejected with a
422. - A key is scoped to the credential that used it, and remembered for 24 hours.