One transaction, no accounts
paperplane has no accounts, no API keys, and no subscription. Every letter is an independent transaction, paid for individually with a Stripe link or a prepaid credit code. This keeps integration trivial and removes any provisioning step. This shapes everything about the API: you never authenticate a caller — you prove ownership of a specific order when doing something sensitive to it.The two kinds of signed tokens
Because there are no accounts, sensitive actions are guarded by HMAC-signed tokens minted by the server.Confirmation tokens (ppq_)
1
Quote
POST /v1/quotes or the quote_letter MCP tool. Free, creates nothing.2
Mint
The quote returns a
confirmation_token bound to the exact recipient, content, class, and price.3
Send
POST /v1/orders requires that token; any change invalidates it. Single-use, 30-minute TTL.Capability tokens (ppc_)
Minted at order creation and returned under capability:
Both are bound to the order id and the action, and expire after 7 days. Possession of an order id alone is never enough for these actions.
Order lifecycle
Mail formats
mail_class (above) is the USPS service level — how a piece travels. A
separate format field on POST /v1/orders (and, as of this page, on
quote_letter/send_letter too — see MCP) picks the
physical piece itself, and defaults to letter so every existing
integration is unaffected.
Postcards and the notecard are message-only today: the
text you send
prints directly onto the piece in a real handwriting font — there’s no
custom photo or artwork side, and no PDF/upload path for either format.
Printing and First-Class postage are both bundled into the flat price shown
above, so an order for either one carries no separate USPS postage line.
Both allow only mail_class: "first_class" — they cannot go certified,
priority, or carry tracking; send a letter instead if you need proof of
delivery. The difference between them is privacy: a postcard is open-face
(readable by anyone who handles it in transit), while the notecard is
folded and enclosed like an ordinary greeting card.
The error contract
Every failure returns a machine-readable envelope:code— stable. Never parse thereasonstring.next— the recovery playbook. An agent can act on it directly.
Sandbox vs live
Sandbox mode runs the complete flow — rendering, screening, simulated fulfillment with tracking — instantly and free, with zero keys. The whole API is testable before a real card or real mail is involved. You never have to infer which mode a request ran in: it’s thesandbox
flag you passed, echoed back unambiguously on every order as order.sandbox
(true/false), and sandbox order ids carry an ord_test_ prefix instead of
ord_.