Browse the documentation

Securing your keys

A key is a credential. Four settings bound what a leaked one would allow.

Service restriction

By default a key reaches every service on the account. You can give it an explicit list.

RestrictionDetail
Maximum200 services per key
Outside the list404 SERVICE_NOT_FOUND, the same answer as for another account's service
Where to read itGET /mekey.allServices (boolean) and key.serviceCodes (array of codes, empty when allServices is true)

A restricted key lists only its own services in GET /services.

Address allowlist

AllowlistDetail
Rule formata literal IPv4 or IPv6 address (203.0.113.7, 2a01:e0a::1) or a CIDR block (203.0.113.0/24)
Rule length64 characters at most
Maximum32 rules per key
Emptyevery address is accepted
Refused on savea /0 prefix, a zone index (fe80::1%eth0), a host name. Names are never resolved
Outside the list403 API_KEY_IP_NOT_ALLOWED, logged against the key, plus an email to the holder (at most one a day per key)
Where to read itGET /mekey.ipAllowlist

Expiry

ExpiryDetail
Typeepoch milliseconds, or null for a key that never expires
Where to read itGET /mekey.expiresAt
Afterwards403 API_KEY_EXPIRED
Noticean email seven days ahead

An expired key cannot be rotated. Create a new one.

Spending cap

Mandatory as soon as the key carries billing.saved_methods:charge.

CapDetail
Unitcents
Bounds1 € to 10 000 €, 100 € by default
Windowrolling 30 days
Countsstored-method charges this key triggered, renewals included
Does not countprepaid balance payments
Over the cap403 API_KEY_SPENDING_CAP_EXCEEDED, before any call to the payment provider
Where to read itGET /me or GET /me/keykey.spendingCapCents and key.spendingRemainingCents

Habits

  • One key per integration, named after it.
  • Only the permissions the integration uses.
  • The service restriction as soon as the key touches one service.
  • The address allowlist as soon as the calling machine has a fixed address.
  • An expiry when the use is dated.
  • billing.saved_methods:charge only where a charge is needed, with a cap sized to the job.
  • The secret in an environment variable, a secret manager, or a file readable by the service account alone. Never in a repository, a Docker image, a client-side application or a chat.
  • Never in a URL: the API refuses that with 400 API_KEY_IN_QUERY, but the URL has already been through the proxy logs.
  • Periodic rotation if your policy asks for it: same settings, old secret killed at the same instant.

If a key leaks

  1. Revoke it under Account > API keys, or rotate it if the integration has to keep running. Effect on the next call.
  2. Read its request log: 30 days of routes, statuses, addresses and X-Request-Id.
  3. Check its reach: its service list, its permissions, its cap. A key without billing.saved_methods:charge charged no payment method.
  4. Re-read recent orders and payments in the dashboard.
  5. Write to support with the X-Request-Id values involved.

Support never asks for a key secret, and cannot read one back.