API Keys
Every request your backend makes to the ShotPay API carries two headers, and both are required:
| Header | Value | Secret? |
|---|---|---|
X-Client-Id |
mch_test_ or mch_live_ followed by 32 characters. |
No. It identifies; it does not authorise. |
X-Api-Key |
sk_test_ or sk_live_ followed by 32 characters. |
Yes. |
X-Client-Id: mch_test_7fL2qXn4WbTzR9kD1sVyH6mCgA8eUpJ3
X-Api-Key: sk_test_a1b2c3d4e5f6g7h8i9j0k1l2m3n4o5p6
A valid key presented against a client id it does not belong to authenticates
nothing. A rejected pair answers 401 without saying which half was wrong.
One client id per mode
A merchant holds two client ids — one for sandbox, one for live — and the
dashboard's mode toggle decides which one the API keys page shows you. The two
headers must agree on mode: a mch_test_ id paired with an sk_live_ key is
refused.
Keys are server-side secrets
Keep the key server-side
The key is a secret. Store it and use it only on your server — never in front-end JavaScript or anywhere else a browser can read it.
A key is shown once, at issuance, and cannot be recovered afterwards — a lost
key is replaced, not retrieved. The dashboard lists only the key_prefix, the
first 12 characters, for telling two keys apart.
The key decides the mode
The prefix decides which half of the account a request belongs to:
| Prefix | Mode | Reads and writes |
|---|---|---|
sk_test_ |
Sandbox | Sandbox data only. Payments are simulated. |
sk_live_ |
Live | Live data only. Real money. |
A sandbox key can never read live data, or the other way round. Settings and webhook endpoints are held per mode too, so the two halves can be configured differently and neither can surprise the other.
See Sandbox for what sandbox mode gives you.
The customer-facing routes carry no key at all — the session token in the URL is the credential.
Rotating and revoking
A revoked key stops authenticating immediately.
To rotate without downtime: issue the new key, deploy it, confirm with
GET /v1/ping that the new key resolves to the right merchant, then revoke
the old one.
What a key does not survive
A key keeps working while its merchant is cleared to transact in that key's
mode. So a sandbox key keeps working while an FFL licence is in review, and only
the live key waits on it. Both stop if the account is suspended, or if it has not
been approved — approval is what opens sandbox in the first place, so a key
cannot outlive it. Every refused request answers 403 with no reason.