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'| Type | Held by | Can 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.
Sandbox and production keys live on the same account. Create either at any time:
gateway.sandbox.paayed.com.account_inactive — build and configure your integration before go-live, and nothing changes on the day.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.
| Scope | Grants |
|---|---|
payments.read / payments.write | List/retrieve payments; create, capture, cancel |
payments.card.raw | Send a card number directly. Requires a PCI attestation on file. |
payments.merchant_initiated | Charge a stored card without the cardholder present |
refunds.read / refunds.write | List/retrieve refunds; create refunds |
customers.read / customers.write | Read and manage customers |
payment_methods.read / payment_methods.write | Read stored cards; attach and detach them |
subscriptions.read / subscriptions.write | Read and manage schedules |
events.read | Read the event log |
webhooks.write | Manage webhook endpoints and rotate their secrets |
tokens.create | Publishable keys only: exchange card details for a single-use token |
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.
Deploy the new key
Both keys work during the grace period — take your time.
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).
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.
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.
The credential is valid but doesn't carry the scope the route requires. The error body names the missing scope directly.
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.
Always accompanied by a Retry-After header and RateLimit-* headers on every response, not just on 429s.