API keys
Create, scope, rotate, and revoke 505pay API keys — plus the playbook for a leaked key
API keys are the credentials your server uses to call the Payments Service on behalf of a merchant. They are scoped to a single merchant and a single environment (sandbox or production). Each key has a unique prefix that lets you identify which key was used in logs.
Keys are shown once
The full key value is returned once at creation and never again. Store it in a secrets manager (AWS Secrets Manager, HashiCorp Vault, .env file for local dev only) immediately after creation.
Create a key
curl -X POST https://sandbox.505pay.link/v1/payments/settings/api-keys \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"name": "production-server", "scopes": ["payments.payment_intent.create", "payments.payment_intent.read"]}'The response includes key (full value, shown once) and id (use for revocation).
List keys
curl https://sandbox.505pay.link/v1/payments/settings/api-keys \
-H "Authorization: Bearer $ACCESS_TOKEN"Only the key prefix and metadata are returned — never the full key value.
Scoping per environment
| Environment | Hostname | Key prefix |
|---|---|---|
| Sandbox | sandbox.505pay.link | sk_test_… |
| Production | api.505pay.link | sk_live_… |
Sandbox keys (sk_test_…) do not work in production and production keys (sk_live_…) do not work in sandbox. The prefix is enforced at the database level: a sk_test_… key presented to a production-configured Payments Service returns 403 env_mismatch. This is a runtime invariant — we will not promote a test key by accident.
Scopes for hosted checkout
Each API key is created with an explicit scopes list. The hosted-checkout flow (POST /v1/payments/intents) requires the payments.payment_intent.create permission.
| Scope | Endpoint(s) | Notes |
|---|---|---|
payments.payment_intent.create | POST /v1/payments/intents | Required for hosted-checkout integrations. Issue a dedicated key with just this scope for your checkout backend. |
payments.payment_intent.read | GET /v1/payments/intents, GET /v1/payments/intents/{id} | Allows status polling. Optional — most integrators rely on webhooks. |
payments.payment_intent.cancel | POST /v1/payments/intents/{id}/cancel | Allows programmatic cancellation. |
payments.refund.create | POST /v1/payments/refunds | Required to issue refunds programmatically. |
Keys without the required scope receive a deterministic 403 insufficient_scope envelope:
{
"error": "insufficient_scope",
"message": "API key lacks the required scope: payments.payment_intent.create",
"request_id": "req_018f4d9f"
}This decision is made in-process by the Payments Service — the bearer is never forwarded to the identity service, so a missing scope cannot be confused with an expired or revoked key.
Practice least privilege: issue a separate key with only payments.payment_intent.create for your checkout backend. The refund handler should run with its own key scoped to payments.refund.create. A leaked checkout key cannot then be used to refund payments to an attacker-controlled card.
Rotation procedure
Rotate keys on a schedule (every 90 days recommended) or immediately after a suspected leak.
Create a new key
Create the replacement key before revoking the old one to avoid a gap in service:
curl -X POST https://sandbox.505pay.link/v1/payments/settings/api-keys \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-d '{"name": "production-server-2026-08"}'Store the new key value in your secrets manager.
Deploy the new key
Roll out the new key to all server instances. Verify calls succeed before continuing.
Revoke the old key
curl -X DELETE https://sandbox.505pay.link/v1/payments/settings/api-keys/$OLD_KEY_ID \
-H "Authorization: Bearer $ACCESS_TOKEN"Revocation is immediate — any in-flight request using the old key will receive 401 Unauthorized.
Leaked key playbook
If a key is found in a public repository, log file, or error report:
- Revoke immediately — do not wait for rotation window. Use the revoke endpoint above.
- Check access logs — scan Payments Service logs for the key prefix (visible in logs) for the past 30 days.
- Assess blast radius — look for unexpected
createPaymentIntent,createRefund, orupdatePayoutSettingscalls. - Create a replacement key and deploy.
- Notify the security team if there is evidence of unauthorised use.
Multi-key overlap window
During rotation you will briefly have two live keys. This is intentional — the overlap window should be no longer than one deploy cycle (typically under 30 minutes). Do not leave redundant keys active after deployment is confirmed.
Related
- API Reference — list keys
- API Reference — create key
- API Reference — revoke key
- Authentication guide
Was this page helpful?