Authentication and API keys
Secret keys, publishable keys, scopes, IP allowlists, expiry and rotation.
Authenticate every request with a secret API key sent as a bearer token:
curl https://zylopay-api.fly.dev/api/v1/payments \
-H "Authorization: Bearer zp_test_sk_…"Requests without a valid key answer 401 with type: "authentication_error".
Key format
zp_<mode>_<type>_<40 characters>
zp_live_sk_4eC39HqLyjWDarjtT1zdp7dcA1b2C3d4E5f6G7h8| Part | Values |
|---|---|
| mode | test (Monad testnet sandbox) or live (Monad mainnet). The key alone chooses the network. |
| type | sk secret, for your servers. pk publishable. |
The zp_ prefix lets secret scanners, such as GitHub push protection, recognise a leaked key.
Publishable keys (zp_…_pk_…) carry no scopes and are refused by every endpoint today (403 publishable_key_not_allowed). They are reserved for future client-side flows. Use a secret key from your server.
Create and manage keys
Keys are managed in the dashboard, Developers → API keys, by owners and admins. Every member can see the list. Each change (create, rotate, revoke, delete) is recorded in the Audit log tab with who made it.
- The full key is shown once, at creation or rotation. The list shows only its prefix and last four characters (
zp_live_sk_4eC3…G7h8) and when it was last used. - Live keys need an approved business verification. Until then the dashboard disables the Live option and the API refuses with
KYB_REQUIRED. Test keys are always available. - An account can hold up to 50 keys. Delete revoked keys to make room.
Scopes
A secret key carries one or more scopes. Each endpoint requires one; a key without it gets 403 insufficient_scope. New keys get every scope by default. Give each system only what it needs.
| Scope | Grants |
|---|---|
payments:read | List and retrieve payments and payment intents. |
payments:write | Create and cancel payment intents on your terminals. |
refunds:read | List and retrieve refunds. |
refunds:write | Create refunds. |
terminals:read | List and retrieve terminals. |
balance:read | Read the account balance. |
events:read | List and retrieve events. |
webhooks:read | List webhook endpoints and their delivery logs. |
webhooks:manage | Create, update, delete webhook endpoints, rotate secrets, resend and send test events. |
Examples:
- A reporting job:
payments:read,refunds:read,balance:read. - An ordering system that sends payments to terminals:
payments:write,payments:read,terminals:read. - A support tool that refunds:
refunds:write,refunds:read,payments:read.
IP allowlist
Optionally restrict a key to your servers' addresses: up to 50 IPv4 or IPv6 addresses or CIDR ranges (203.0.113.10, 198.51.100.0/24). A request from any other address answers 403 ip_not_allowed. An empty list allows any address. Use it for every live key whose callers have fixed egress IPs.
Expiry
A key can have an expiry date. After it, requests answer 401 api_key_expired. A revoked key answers 401 api_key_revoked.
Rotation
Rotate a key in the dashboard (Rotate). Rotation creates a new key with the same name, scopes and allowlist, and keeps the old key working for an overlap window: 24 hours by default, from 0 (the old key stops at once) to 168 hours. Deploy the new key within the window.
- Rotate. Store the new key in your secrets manager.
- Deploy it to every service that uses the old key.
- Check Last used on the old key: it should stop moving.
- Let the overlap end, or revoke the old key.
If a key leaks, rotate with an overlap of 0, or revoke it. Then read the audit log and your request logs for the period.
Where the key must never be
- In a browser, a mobile app or a POS app. Terminals use their own device keys, provisioned in the dashboard.
- In source control, CI logs or error trackers.
- In a URL. ZyloPay redacts keys from its own logs, but proxies and browsers may not.
Disabled accounts
If your account is disabled, read requests keep working and every write answers 403 account_disabled. Contact support.