Skip to main content

Email → letter

Send an email to paperplane’s inbound address and it turns the thread into a letter order. Two ways to give it the recipient and the letter: Just write it like a normal email, in your own words:
paperplane replies asking whatever it’s missing — an address, the actual wording — quotes a real price, and mails nothing until you reply to confirm that specific quote. Or use the TO:/FROM: block convention — the fast path, priced instantly with no model call at all:
The FROM: block is optional but recommended — USPS requires a return address on every physical piece, and when it’s present it becomes the order’s actual return address instead of paperplane’s placeholder one. SEND EXACTLY: marks the letter text as final, to mail word for word; use DRAFT FOR ME: instead with a description of what you want said, and the natural-language layer (step 3 below) drafts it for you — the deterministic TO:-block parser has no drafting capability of its own, so a DRAFT FOR ME: email always falls through to that layer, even with a well-formed TO: block. The TO:/FROM: blocks and the SEND EXACTLY:/DRAFT FOR ME: labels are all stripped before mailing, so the letter reads cleanly.

What happens

  1. We receive the email and verify it (Svix-signed webhook).
  2. We try the deterministic TO:-block parser first — it’s free, instant, and unambiguous, so a well-formed email never invokes a model at all for pricing. If it finds a valid TO: block, a real address, and usable letter text (a SEND EXACTLY: section, or the whole remainder when neither label is used), it prices the letter and replies with a quote — nothing is mailed yet. A DRAFT FOR ME: section, or no letter text at all, falls through to step 3 instead.
  3. If the body doesn’t match that shape (or used DRAFT FOR ME:), an AI read of the email extracts a recipient and drafts or cleans up the letter content from the natural prose or description, asking a clarifying follow-up by replying to the thread if anything is missing or ambiguous. Once it has both, it gets a real price and replies with a quote — nothing is mailed yet.
  4. Only an explicit confirming reply to that specific quote (in a later message) completes the order and mails it; a model output is never enough on its own, the same safety boundary send by text uses. We reply to that confirming message with the tracking link.
A well-formed TO: block no longer skips the quote — it used to create the order immediately on the first message; it now gets the exact same “here’s the price, reply yes to send it” step every other path gets, so nothing is printed or charged off a single email. Because an email reply carries the whole quoted thread beneath your new text, paperplane looks only at what you actually wrote — above the quoted > lines, the “On … wrote:” header, or an Outlook-style separator — when deciding whether a reply is a confirmation.

Why the TO: block is tried first here, unlike text

Send-by-text tries its conversational layer first and only falls back to strict parsing if the model is unavailable, because a text sender is almost always a person free-texting. Email is different: anyone integrating with the documented TO: convention — a script, an automation, a person who read this page — gets instant, free, zero-ambiguity handling every time, and only a human writing in ordinary prose that doesn’t match it pays for a model call at all.

Notes

  • The recipient must be a real USPS-verifiable address, same as every other surface.
  • If neither the TO: block nor the natural-language layer can find enough to work with (and the natural-language layer isn’t configured, or is unavailable when it’s needed), you’ll be asked to add a recipient rather than have one guessed.
  • A confirming reply only ever completes the specific quote it was sent for — the recipient, letter content, and price are bound to a single-use token, the same mechanism every other surface uses.
  • Test mode: use sandbox-mode orders to test the full flow for free before sending real mail.
Last modified on September 16, 2026