Every request except GET /catalog is authenticated. This page covers the two kinds of credential, the scopes they carry, and the sending permissions that let them spend your credits.
Send credentials as a bearer token over HTTPS:
Authorization: Bearer <api-key-or-token>GET /catalog is public. Every other endpoint needs a credential, and you can only reach resources your own account owns. Browser cookies don't work for /api/v1.
There are two kinds of credential:
| API key | OAuth | |
|---|---|---|
| Used by | Your own code, over HTTP | AI assistants such as ChatGPT and Claude, over MCP or HTTP |
| Created by | You, in Account → Credits → API keys | The assistant's sign-in flow on Pony |
| Format | pony_live_…, or pony_test_… for test mode |
Short-lived access tokens |
| Lifetime | One year by default, or until revoked | Short-lived, refreshed by the assistant |
API keys#
The simple form on Account → Credits → API keys asks for a name and an optional daily limit. In one step it creates:
- a key with the scopes
letters:read,letters:write,orders:read,orders:send,orders:cancel,wallet:read,grants:readandwebhooks:write, valid for one year - the key's own sending permission, capped by the daily limit if you set one
So a new key can write letters, send them from your balance and manage webhooks straight away. Sending with it needs no grant_id.
For a narrower key, such as a read-only reporting key, open Advanced: choose scopes and an existing permission. There you pick the scopes, the expiry and, optionally, an existing permission to bind the key to.
The secret is shown once. Store it in a secret manager or a file only you can read. Don't put it in a URL, a log, a chat or a code repository. Revoking a key on the same page stops it at its next request.
OAuth#
AI assistants connect through Pony's OAuth sign-in; see Connect an assistant. If you build your own OAuth client, discover the authorization server from https://www.mailbypony.com/.well-known/oauth-protected-resource rather than hard-coding it. Use the authorization code flow with PKCE (S256), and check the issuer and resource. Each client needs its own registration and your consent; a script can't reuse an assistant's connection.
Scopes#
| Scope | Allows |
|---|---|
letters:read |
Read your drafts, proofs and address references; render proofs |
letters:write |
Create, edit, archive and attach files to drafts; manage templates |
drafts:read, drafts:write |
Aliases for letters:read and letters:write |
addresses:read |
List confirmed address references |
wallet:read |
Read your balance, credit history and top-up status |
wallet:topup |
Create a payment link to add credits. It can't charge a card. |
grants:read |
Read the sending permissions that apply to this credential |
orders:send |
Request final quotes and send letters within a sending permission |
orders:read |
Read your orders and batches |
orders:cancel |
Cancel orders, if the order's sending permission allows it |
webhooks:write |
Register, list, test and remove webhook endpoints (HTTP only) |
checkout:write |
Start a card checkout that you finish in your browser |
No scope lets a credential create or widen a sending permission, or create other keys. Only you can, on the website.
Sending permissions#
A sending permission (called a grant in the API) lets one key or assistant send letters from your credits without asking you each time. API keys from the simple form get one automatically. For an assistant, open Account → Credits → Let my assistant send letters, enter the assistant's client ID (ask it to run get_connection_identity) and an optional daily limit.
Every restriction is optional. Leave one out and it doesn't apply:
| Restriction | Field |
|---|---|
| Maximum spend per day (resets at midnight UTC) | daily_limit_minor |
| Maximum price for one letter | per_order_minor |
| Maximum spend over the permission's life | lifetime_limit_minor |
| Maximum number of letters | count_limit |
| Allowed recipients and senders | recipient_ids, sender_ids |
| Allowed papers, envelopes and type styles | papers, envelopes, styles |
| Expiry (default one year) | expires_at |
| Whether it may cancel orders (default yes) | allow_cancel |
On the website, the restrictions beyond the daily limit are under Advanced limits.
Every limit is checked again at the moment of sending, in the same transaction that deducts credits. A letter cancelled later still counts toward the limits.
To change a permission, revoke it and create a new one. Revoking stops future sends straight away. It doesn't recall letters already accepted.
When you send without a grant_id, Pony uses the newest active permission for your key or assistant.