Skip to main content
agent-nativepay-per-letterno-accountusps-mail

Send mail from agents & apps

paperplane is agent-native: the MCP endpoint and REST API are the product, and the website is one more client of them. No account, no API key, no monthly fee — every order carries its own payment.

Use paperplane with your AI agent

Services

4 flagship formats shown; full price list

from $1.99

Letter

Typed or uploaded, sealed envelope. Certified Mail and Priority both go this way.

$12.99

Certified Mail

USPS proof of mailing + tracking. Add electronic Return Receipt for $14.99.

from $1.99

Postcard

Message-only, no envelope. 4x6, 6x9, or 6x11 — printing and postage included.

$5.99

Card

Folded, handwriting-script card. Enclosed like a greeting card, not open to view.

Plans

Pay as you go

pay per letter

No account, no plan to choose, no purchase needed up front.

Resources

llms.txtFull site index for AI crawlers and assistants.agent.jsonMachine-readable capability card — tools, scopes, safety.openapi.jsonOpenAPI 3.1 spec, generated from the server’s own schemas.DocsFull documentation site — quickstart, guides, API playground.pricing.mdPricing in plain markdown, generated from the live pricing table.auth.mdWhat today’s API does and does not require.mcp/server-card.jsonMCP server card — preview tools before connecting.api-catalogRFC 9727 linkset of every machine-readable surface.

Agent card preview

{
  "name": "paperplane",
  "interfaces": {
    "mcp": { "transport": "streamable-http", "url": "https://sendpaperplane.com/api/mcp" },
    "rest": { "openapi": "https://sendpaperplane.com/v1/openapi.json" }
  },
  "pricing": {
    "model": "per-transaction",
    "currency": "USD",
    "items": [
      { "sku": "first_class", "price": 1.99, "unit": "letter (1 page B&W)" },
      { "sku": "certified", "price": 12.99, "unit": "letter" }
    ]
  },
  "authentication": { "required": false, "scheme": "bearer" }
}

Supported payment methods

Card / Apple Pay Stripe

A hosted checkout link the agent’s human approves — the confirmation step every assistant platform requires before a purchase.

Prepaid credit code pp-xxxx-xxxx-xxxx

No card at all: a prepaid code pays for letters directly. Balance lasts 5 years.

USDC on Base x402Coming soon

For an agent holding its own funded wallet: pay per call with no human checkout step at all. Built and tested — staged until a facilitator account is provisioned.

How agents pay

  1. 01

    Get a quote

    POST /v1/quotes (or the quote_letter MCP tool) prices any letter, free. Returns a confirmation_token bound to the exact recipient, content, class, and price.

  2. 02

    Confirm and pay

    POST /v1/orders with that token returns a Stripe payment link for the human to approve (or, for an agent with its own wallet, settles USDC over x402 once that lane is live — see payment methods above). A send is never the first call.

  3. 03

    Track the letter

    GET /v1/orders/:id (or get_letter_status) reports the lifecycle from screening to delivered.

Prefer a terminal?

npx paperplane wraps the whole thing — quote, send, and check status without writing any code. See the full CLI docs.

npx paperplane send letter.pdf --to "Maria Alvarez, 1 Main St, Richmond VA 23220" --sandbox

Sandbox: pass sandbox: true to run the entire flow — rendering, screening, simulated fulfillment with tracking — instantly and free. An agent's first call can succeed before any human has signed up for anything.

The benchmark, replayed

Claims about being agent-ready are cheap; transcripts aren't. This is the real captured sandbox run — quote → send → track in 3 calls, zero schema retries — including the part where a replayed request and a reused confirmation token both fail to double-send. Full write-up: agent benchmark.

Captured sandbox run · 2026-08-26

quote_letterCall 1 — quote (free, mints the confirmation token)
POST /v1/quotes
{
  "mail_class": "certified",
  "page_count": 1,
  "to": {
    "name": "Property LLC",
    "line1": "1 Main St",
    "city": "Richmond",
    "state": "VA",
    "zip": "23220"
  },
  "text": "Formal demand for return of my security deposit within 14 days of this notice."
}
200
{
  "status": "ok",
  "total_cents": 1299,
  "total": "$12.99",
  "breakdown": [
    {
      "id": "certified_mail_letter_1_page",
      "label": "Certified Mail letter, 1 page",
      "amount_cents": 1299
    }
  ],
  "confirmation_token": "ppq_eyJ2IjoxLCJqdGkiOiJhNDBlZjFiMzFhZDMxYjMx…",
  "expires_in_minutes": 30,
  "next": [
    "POST /v1/orders with this confirmation_token and the same recipient, content, and options."
  ]
}

The next array tells the agent its own next step.

send_letterCall 2 — send (sandbox), with an idempotency key
POST /v1/orders
Idempotency-Key: bench-2026-08-25-a
{
  "mail_class": "certified",
  "sandbox": true,
  "confirmation_token": "ppq_eyJ2IjoxLCJqdGkiOiJhNDBlZjFiMzFhZDMxYjMx…",
  "to": {
    "name": "Property LLC",
    "line1": "1 Main St",
    "city": "Richmond",
    "state": "VA",
    "zip": "23220"
  },
  "from": {
    "name": "Alex Rivera",
    "line1": "12 Grove Ave",
    "city": "Richmond",
    "state": "VA",
    "zip": "23221"
  },
  "text": "Formal demand for return of my security deposit within 14 days of this notice."
}
201
{
  "status": "ok",
  "order": {
    "id": "ord_test_f5ca66ace638fdc1",
    "status": "submitted",
    "sandbox": true,
    "price_cents": 1299,
    "tracking_number": "9400MOCK00000001"
  },
  "corrected_to": {
    "name": "Property LLC",
    "line1": "1 MAIN ST",
    "city": "RICHMOND",
    "state": "VA",
    "zip": "23220"
  },
  "capability": {
    "cancel_token": "…",
    "review_token": "…"
  }
}

Address USPS-standardized, scoped cancel/review tokens minted — no account, no API key.

GET /v1/orders/:idCall 3 — track
GET /v1/orders/ord_test_f5ca66ace638fdc1
200
{
  "status": "ok",
  "order": {
    "status": "submitted",
    "tracking_number": "9400MOCK00000001",
    "…": "…"
  }
}
send_letterSafety proof — replay the exact same order call (same Idempotency-Key)
POST /v1/orders
Idempotency-Key: bench-2026-08-25-a
200replayed: true — no second letter
{
  "status": "ok",
  "replayed": true,
  "order": {
    "id": "ord_test_f5ca66ace638fdc1",
    "…": "…"
  }
}

Same order id. A retry storm mails one letter.

send_letterSafety proof — reuse the confirmation token (new order, same token)
POST /v1/orders
403 action_required

confirmation_used

This confirmation_token was already used to send a letter. Each quote authorises exactly one letter.

next

  • Quote again — POST /v1/quotes (MCP: quote_letter) — to authorise another letter.

Each quote authorises exactly one letter — a reused token cannot double-send.

send_letterSafety proof — tamper with the token
POST /v1/orders
403 action_required

confirmation_malformed

confirmation_token is not a paperplane quote token.

next

  • Quote first: POST /v1/quotes (MCP: quote_letter) with the exact parameters you intend to send, then pass the confirmation_token it returns.

Every failure is a { status, code, reason, next[] } envelope.

Every failure that transcript beat could have ended on, rendered the same way: the full error contract, visually.

MCP: Claude, agents, any MCP client

Pick your client for the exact config. The field name differs more than you would expect.

Step 1

Connect

claude mcp add --transport http paperplane https://sendpaperplane.com/api/mcp

Try it: free, nothing mailed

Tell your agent:

Using the paperplane tools, quote a 1-page certified letter to Property LLC, 1 Main St, Richmond VA 23220, then send it in sandbox mode.

Three tools, deliberately only three:

Look up an order's events

Every order's real event log — screening, submission, provider webhooks — not just its current status. Paste any real order id (yours, or the one the benchmark above just replayed) to see it.

Developer console

Sign in to see your letters in one place — live status, tracking, and receipts — even though sending stays keyless.

Sign in

REST

curl -X POST https://sendpaperplane.com/v1/orders \
  -H 'Content-Type: application/json' \
  -d '{
    "mail_class": "certified",
    "sandbox": true,
    "text": "Formal demand for return of my security deposit...",
    "to":   { "name": "Property LLC", "line1": "1 Main St",
              "city": "Richmond", "state": "VA", "zip": "23220" },
    "from": { "name": "Alex Rivera", "line1": "12 Grove Ave",
              "city": "Richmond", "state": "VA", "zip": "23221" },
    "email": "alex@example.com"
  }'

Try it — a real sandbox round trip

Not a mock. Edit the request below and this calls this deployment's own POST /v1/quotes, then POST /v1/orders with sandbox: true — real screening runs, a real sandbox order is created, nothing is printed, mailed, or charged.

Real calls to this deployment's own API. The send step always sets sandbox: true — nothing is printed, mailed, or charged.

Error contract

Every error is structured for agents: { status, code, reason, next: ["what to do"] }. Address problems return the USPS-corrected candidate. Nothing requires reading HTML or guessing.

Content rules

Every letter is screened before printing (policy). Lawful demand letters and firm legal language are explicitly allowed; threats, fraud, and impersonation are refused and the payment released.

Send your first letter.

The sandbox runs the whole pipeline for free and mails nothing. Live sends start at $1.99.

npx paperplane send letter.pdf \
  --to "Maria Alvarez, 1 Main St, Richmond VA 23220" \
  --from "Alex Rivera, 12 Grove Ave, Richmond VA 23221" \
  --sandbox