Home
Getting Started

Authentication

Secret keys, publishable keys, and how to rotate credentials without downtime.

Every request is authenticated with a bearer credential in the Authorization header:

curl 'https://gateway.paayed.com/v1/payments' \
  -H 'Authorization: Bearer pyd_secret_live_your_key_here'

Credential types

TypeHeld byCan do
Secret key (pyd_secret_live_… / pyd_secret_test_…)Your server only. Never a browser, a mobile app, or a repository.Everything the granted scopes allow, on behalf of one merchant account.
Publishable key (pyd_public_live_… / pyd_public_test_…)Safe to embed in a web page or mobile app.Exchange card details for a single-use token, and read the status of a hosted session it created. Nothing else.
Access token (Bearer eyJ...)A platform acting for many merchants. Minted from a client ID and secret, short-lived.Whatever the token's scopes allow, against whichever merchant it names. Phase 2.

Keys are 48 characters including the prefix. The prefix is part of the credential and is validated, not stripped — a key from another system is rejected outright rather than silently failing somewhere deep.

Environments

Sandbox and production keys live on the same account. Create either at any time:

  • A sandbox key works immediately against gateway.sandbox.paayed.com.
  • A production key is created immediately too, but only authenticates once your account is active. Until then it returns account_inactive — build and configure your integration before go-live, and nothing changes on the day.

Scopes

Every key is scoped. A checkout key that can create payments shouldn't necessarily be able to issue refunds or charge a card off-session.

ScopeGrants
payments.read / payments.writeList/retrieve payments; create, capture, cancel
payments.card.rawSend a card number directly. Requires a PCI attestation on file.
payments.merchant_initiatedCharge a stored card without the cardholder present
refunds.read / refunds.writeList/retrieve refunds; create refunds
customers.read / customers.writeRead and manage customers
payment_methods.read / payment_methods.writeRead stored cards; attach and detach them
subscriptions.read / subscriptions.writeRead and manage schedules
events.readRead the event log
webhooks.writeManage webhook endpoints and rotate their secrets
tokens.createPublishable keys only: exchange card details for a single-use token

Rotation without downtime

1

Roll the key

Call POST /v1/developers/api-keys/{id}/roll from the dashboard, choosing a grace period from one hour to thirty days. A successor key is issued immediately.

2

Deploy the new key

Both keys work during the grace period — take your time.

3

Let the old one expire

Once the grace period ends, the predecessor stops working on its own. No separate revoke step needed.

Revoking a key instead is immediate — the row is marked revoked and the change propagates within the authorizer's cache window (up to five minutes, backed by an immediate denylist check).

Production keys are a step-up action

Creating or rolling a production key requires a second-factor challenge in the dashboard, even if your session is already authenticated. Sandbox keys need no step-up. This is a dashboard control, not something your integration needs to handle.

Error responses

401 authentication_error — missing or invalid credential

The key is missing, malformed, revoked, or expired. Fails fast, with no I/O — this is the cheapest path in the system for a reason: malformed credentials are the bulk of hostile traffic.

403 permission_error — insufficient scope

The credential is valid but doesn't carry the scope the route requires. The error body names the missing scope directly.

403 — source address not allowed

If the key has an address allow list configured, a request from outside it is rejected and the message names the address that was rejected.

429 rate_limit_error — throttled

Always accompanied by a Retry-After header and RateLimit-* headers on every response, not just on 429s.