# API security best practices

How to protect your secret keys, webhooks and integration.

# API security best practices

## Never expose secret keys

- `sk_live_…` and `sk_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 Southbill API from **your server**. From the browser, only ever use the `client_secret` returned by `POST /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 `.env` files 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-Key` header on every `POST` that 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 `Southbill-Signature` header with your `whsec_…` secret.
- Reject signatures older than 5 minutes (replay protection).
- See **Webhooks → Verify signatures**.

## Rate limits

- Per API key, per minute: **120** Checkout Session creates, **300** reads, **60** writes (products, subscriptions, refunds).
- Exceeding returns `429 rate_limited` with a `Retry-After` header. Implement exponential backoff.

## Principle of least privilege

- Create separate keys per environment / service and revoke unused ones.
- Keys are scoped — create one key per service with only the scopes it needs (`checkout:write`, `refunds:write`, `products:write`, …).

## Incident response

If a key is leaked:

1. Revoke it in the Dashboard immediately — all requests using it start returning `401`.
2. Create a new key and deploy it.
3. Review the Developers → Request log for suspicious traffic.
4. Contact support@southbill.com if funds were moved that you did not authorise.

