API security best practices
How to protect your secret keys, webhooks and integration.
API security best practices
Never expose secret keys
sk_live_…andsk_test_…grant full merchant access. Never ship them in browser code, mobile apps, git repos, logs, error reports, or client-side analytics.- Always call the spuke API from your server. From the browser, only ever use the
client_secretreturned byPOST /v1/checkout/sessions. - Rotate keys immediately if you suspect a leak (Dashboard → Developers → Revoke).
Separate test and live
sk_test_…keys only work in test mode and never move real money. Use them for CI, staging and local development.- Live keys should be stored in your production secret store (AWS Secrets Manager, Vault, GitHub Actions Secrets, etc.) — never in
.envfiles committed to git.
Enforce TLS
- The API only accepts requests over HTTPS (TLS 1.2+). Plaintext HTTP is rejected.
- Verify TLS certificates in your HTTP client. Disabling verification defeats the point.
Always use Idempotency-Keys
- Send an
Idempotency-Keyheader on everyPOSTthat creates money-moving objects. - Use a stable value per business action (e.g.
order_12345) — not a random UUID per retry. - See Checkout Sessions → Idempotency.
Verify webhook signatures
- Never trust a webhook body without verifying the
Spuke-Signatureheader with yourwhsec_…secret. - Reject signatures older than 5 minutes (replay protection).
- See Webhooks → Verify signatures.
Rate limits
- Default: 100 requests / second per merchant, burst 200.
- Exceeding returns
429 rate_limitedwith aRetry-Afterheader. Implement exponential backoff.
Principle of least privilege
- Create separate keys per environment / service and revoke unused ones.
- Per-scope keys (
checkout:writeonly,refunds:writeonly, …) are on the roadmap.
Incident response
If a key is leaked:
- Revoke it in the Dashboard immediately — all requests using it start returning
401. - Create a new key and deploy it.
- Review the Developers → Request log for suspicious traffic.
- Contact support@spuke.com if funds were moved that you did not authorise.