> ## 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.

# Rate limits

> Velocity and spend caps that keep the free, keyless model safe from abuse.

## Why caps exist

Because paperplane is **keyless** (no accounts), it can't identify callers by credential. So it enforces abuse limits on two dimensions, keyed by how it can attribute the request.

## The two caps

<ResponseField name="sender cap" type="number">
  Friendly cap per **sender identity** (caller + declared sender email). This is the number a normal user notices.

  * 5 letters/day, 20/month
</ResponseField>

<ResponseField name="actor cap" type="number">
  Enforcement cap per **actor** (API key id, else the client IP). Nothing the caller supplies varies the key, so changing the email can't escape it. Sits higher so a shared office NAT still works.

  * 15 letters/day, 60/month, **$50/day, $200/month** spend
</ResponseField>

Spend caps are counted in cents on the same actor key and are independent of the letter-count caps.

## What a cap hit looks like

```json theme={null}
{
  "status": "failed",
  "code": "velocity_limit",
  "reason": "Sending limit reached for this credential (15/day, 60/month across all senders).",
  "next": ["Wait for the window to roll over, or contact support for a verified higher-volume account."]
}
```

## Verifying a caller

Attribution strategies:

* Any `email` you pass works as part of the sender fingerprint.
* A **verified account** (launch-phase feature) lifts these caps; until then it's per-IP with the ceilings above.

<Note>
  If a request can't be attributed at all, it's **refused** with a clear error rather than let through unlimited (fail-closed), because we can't apply limits we can't attribute.
</Note>

## Per-instance throttles

Separately from the sender/actor caps above, a handful of routes carry their
own simple per-minute throttle — a speed bump against scripted abuse, not the
billing-abuse boundary the caps above are for. Each is keyed on the API key
when one is present, else the caller's IP, and returns `rate_limited` with
`Retry-After` like any other 429.

| Route                                  | Limit     |
| -------------------------------------- | --------- |
| `POST /v1/orders` with `sandbox: true` | 20/minute |
| `POST /v1/credits/checkout`            | 10/minute |
| `POST /v1/uploads`                     | 10/minute |
| `POST /v1/csv-map`                     | 10/minute |
| `POST /v1/suggest-class`               | 10/minute |
| `GET /v1/address/autocomplete`         | 30/minute |
| `POST /v1/address/reverse`             | 30/minute |

## Sandbox is not exempt from throttling

Sandbox orders skip the sender/actor caps above entirely — they cost no
postage, so they don't count against your 5/day or 15/day sending limits. But
a sandbox order still runs the real (billed) content screener and renders or
fetches a PDF, and the endpoint is reachable with no API key at all, so it
carries its own 20/minute throttle (the first row of the table above) as a
floor against generating unlimited billed screening calls for free. That
throttle is a different code path from the sender/actor caps, and does not
share their daily/monthly windows.

## Do this

* **Build perks/bulk in mind:** stay under 15/day or contact for a verified account.
* **Handle `velocity_limit` in code** — surface the `next` message, don't silently retry forever.
* Sandbox testing is generous (20 sandbox orders/minute) but not unlimited — see above.
