> ## Documentation Index
> Fetch the complete documentation index at: https://paperplane-justin-winter-s-projects.vercel.app/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Core concepts

> Tokens, security, and the mental model for how paperplane works.

## 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 paperplane payment 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_`)

<img className="block dark:hidden" src="https://mintcdn.com/paperplane-524ba6ed/ZBGL6ddb_oTreKCb/images/illustrations/pipeline-light.svg?fit=max&auto=format&n=ZBGL6ddb_oTreKCb&q=85&s=3211a3c82d4ad9bd3632e1d0add918ce" alt="Quote, confirm, send: POST /v1/quotes prices the letter for free, the confirmation_token holds for 30 minutes, POST /v1/orders creates the order, and the piece is tracked from the print facility to the mailbox." width="720" height="300" data-path="images/illustrations/pipeline-light.svg" />

<img className="hidden dark:block" src="https://mintcdn.com/paperplane-524ba6ed/ZBGL6ddb_oTreKCb/images/illustrations/pipeline-dark.svg?fit=max&auto=format&n=ZBGL6ddb_oTreKCb&q=85&s=73a1602f3af18d2b36f19f2ad3bf7e9b" alt="Quote, confirm, send: POST /v1/quotes prices the letter for free, the confirmation_token holds for 30 minutes, POST /v1/orders creates the order, and the piece is tracked from the print facility to the mailbox." width="720" height="300" data-path="images/illustrations/pipeline-dark.svg" />

<Steps>
  <Step title="Quote">
    `POST /v1/quotes` or the `quote_letter` MCP tool. Free, creates nothing.
  </Step>

  <Step title="Mint">
    The quote returns a `confirmation_token` bound to the exact recipient, content, class, and price.
  </Step>

  <Step title="Send">
    `POST /v1/orders` requires that token; any change invalidates it. Single-use, 30-minute TTL.
  </Step>
</Steps>

This guarantees **a send is never the first call** — an agent must quote first, and cannot send a letter for content it never priced.

### Capability tokens (`ppc_`)

Minted at order creation and returned under `capability`:

| Token | Grants | Required by |
| - | - | - |
| `cancel_token` | Cancel the order + release any payment hold | `DELETE /v1/orders/{id}` via `X-Capability-Token` |
| `review_token` | Post a review attributed from the return address | `POST /v1/reviews` |

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

```
draft → pending_payment → screening → held_for_review ─┬─ allowed → submitted → mailed → delivered
                           (payment)                     └─ refused  → refunded
```

| State | You can |
| - | - |
| `draft` | Cancel |
| `pending_payment` | Cancel (releases hold) |
| `screening` | Cancel |
| `held_for_review` | Cancel |
| `submitted` | Track. Too late to cancel. |
| `mailed` | Track |
| `delivered` | Review |
| `refused` | Re-create the order |
| `canceled` | — |
| `failed` | Re-create the order |

## 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](/docs/guides/mcp)) picks the
physical *piece* itself, and defaults to `letter` so every existing
integration is unaffected.

| `format` | Price | What it is |
| - | - | - |
| `letter` (default) | from \$0.99 | Typed or uploaded, sealed envelope. The only format that can go `certified`/`priority`. |
| `letter_windowed` | \$1.99 | Same sealed envelope, typed or uploaded, up to 12 pages — the address shows through a window instead of being printed separately. `first_class` only, same as the message-only formats below, but this one is NOT message-only: it takes the same `text`/PDF input as `letter`. |
| `notecard` | from \$1.99 | Folded card, message only — see below. Enclosed like a greeting card, not open-face. $1.99 with handwritten typography, $2.99 with a real pen. |
| `postcard_4x6` | \$0.99 | Open-face postcard, message only — see below. |
| `postcard_6x9` | \$2.99 | Larger postcard, same rules. |
| `postcard_6x11` | \$3.49 | The biggest postcard. |

Postcards and the notecard are **message-only today**: the `text` you send
prints directly onto the piece — 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.

### Notecard handwriting

Notecards start at $1.99 and can include handwritten typography
(`"handwriting": "script"`, the default). For $1 more, a robot hand-writes it
with a real pen in real ink, on the same card (`"handwriting": "pen"`, \$2.99).
`handwriting` applies to the notecard only. A notecard quote returns both
prices in `handwriting_options`, and the choice is bound into the
`confirmation_token` alongside recipient, content, class, format and price:
a token quoted for one tier is refused for the other. Where the pen option is
not available to mail, the send is refused before anything is charged, with
`handwriting_pen_unavailable`.

```json theme={null}
{
  "mail_class": "first_class",
  "format": "postcard_4x6",
  "text": "Wish you were here! See you next week.",
  "to":   { "name": "Sam Rivera", "line1": "12 Grove Ave", "city": "Richmond", "state": "VA", "zip": "23221" },
  "from": { "name": "Alex Rivera", "line1": "1 Main St", "city": "Richmond", "state": "VA", "zip": "23220" }
}
```

```json theme={null}
{
  "mail_class": "first_class",
  "format": "notecard",
  "text": "Happy birthday! Hope your day is a great one.",
  "to":   { "name": "Sam Rivera", "line1": "12 Grove Ave", "city": "Richmond", "state": "VA", "zip": "23221" },
  "from": { "name": "Alex Rivera", "line1": "1 Main St", "city": "Richmond", "state": "VA", "zip": "23220" }
}
```

## The error contract

Every failure returns a machine-readable envelope:

```json theme={null}
{
  "status": "failed",
  "code": "file_too_large",
  "reason": "PDF is 12.3MB; limit is 10MB",
  "next": ["Compress the PDF or split it into smaller documents."]
}
```

* `code` — stable. Never parse the `reason` string.
* `next` — the recovery playbook. An agent can act on it directly.

## Sandbox vs live

[Sandbox mode](/docs/sandbox) 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 the `sandbox`
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_`.

## Glossary

Postal and mail-industry terms used throughout this API (CASS certification,
Certified Mail, the Intelligent Mail barcode (IMb), NCOALink, and more) are
defined in the public [glossary](https://sendpaperplane.com/glossary) — the
same terminology this documentation uses.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.