Skip to content
StraventaDocs
Guides

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

EnvironmentHostnameKey prefix
Sandboxsandbox.505pay.linksk_test_…
Productionapi.505pay.linksk_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.

ScopeEndpoint(s)Notes
payments.payment_intent.createPOST /v1/payments/intentsRequired for hosted-checkout integrations. Issue a dedicated key with just this scope for your checkout backend.
payments.payment_intent.readGET /v1/payments/intents, GET /v1/payments/intents/{id}Allows status polling. Optional — most integrators rely on webhooks.
payments.payment_intent.cancelPOST /v1/payments/intents/{id}/cancelAllows programmatic cancellation.
payments.refund.createPOST /v1/payments/refundsRequired 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:

  1. Revoke immediately — do not wait for rotation window. Use the revoke endpoint above.
  2. Check access logs — scan Payments Service logs for the key prefix (visible in logs) for the past 30 days.
  3. Assess blast radius — look for unexpected createPaymentIntent, createRefund, or updatePayoutSettings calls.
  4. Create a replacement key and deploy.
  5. 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.

Was this page helpful?

On this page