Skip to main content
For developers & AI agents

Send a real letter from your app or your AI agent

Premier Letters writes letters, cards and postcards with a real pen and mails them via USPS — from $4.60 per letter, plus postage. Quote, preview, create and track orders with a REST API or a remote MCP server built for Claude, ChatGPT, and any MCP-compatible agent.

For AI assistants: connect in three calls

The user does not need to copy an API key. The assistant asks for one, the account owner approves a single email, and the assistant receives the key once.

  1. connect_account (MCP, no key) or POST /api/v1/agent/connect with the user's email and your name. Show the user the returned user_code.
  2. The user approves the emailed link; meanwhile poll check_connection (or the poll_url) every 10–30 seconds until it returns the api_key.
  3. create_order with the key, an idempotency_key and a return_address.
POST /api/v1/agent/connect
curl -X POST https://www.premierletters.com/api/v1/agent/connect \
  -H "Content-Type: application/json" \
  -d '{ "email": "owner@example.com", "agent_name": "Claude" }'

# 202 -> { request_id, poll_url, poll_secret, user_code, expires_at, instructions }
# Show the user user_code, then poll every 10-30 seconds:
curl "https://www.premierletters.com/api/v1/agent/connect/<request_id>?secret=<poll_secret>"
# -> { "status": "pending" } ... then once: { "status": "approved", "api_key": "pl_live_..." }

Quick start

Generate a key at Settings → API keys, then validate an order (free, no charge) and create one when you're ready to send it.

1. Validate & price a letter

POST /api/v1/validate
curl -X POST https://www.premierletters.com/api/v1/validate \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer pl_live_xxxxx" \
  -d '{
    "message": "Dear Jane,\n\nThank you for your business.",
    "recipients": [{
      "first_name": "Jane", "last_name": "Doe",
      "address_line1": "123 Main St", "city": "Austin", "state": "TX", "zip": "78701"
    }]
  }'

2. Create and pay for the order

POST /api/v1/orders
curl -X POST https://www.premierletters.com/api/v1/orders \
  -H "Content-Type: application/json" \
  -H "Authorization: Bearer pl_live_xxxxx" \
  -H "Idempotency-Key: thank-you-jane-001" \
  -d '{
    "message": "Dear Jane,\n\nThank you for your business.",
    "recipients": [{
      "first_name": "Jane", "last_name": "Doe",
      "address_line1": "123 Main St", "city": "Austin", "state": "TX", "zip": "78701"
    }],
    "return_address": {
      "name": "Acme Dental", "address_line1": "100 Congress Ave",
      "city": "Austin", "state": "TX", "zip": "78701"
    },
    "payment": { "method": "checkout_session" }
  }'

Pricing is from $4.60 per letter, plus postage (passed through at face value). The first 300 characters are included; every additional 100 characters adds $0.75. We write and mail within 2 business days; USPS First-Class delivery then typically takes 3–5 business days.

Placing a correct order

Return address

Pass return_address on envelope orders, or omit it to use the account default. With neither, set no_return_address_ack: true or the order is refused (400 no_return_address_unacknowledged). The response says which was used in return_address.source.

Details

Printed output

options.output_mode is handwritten (default), printed_bw or printed_color for the letter body; options.envelope_output_mode prints the envelope. Quote either with /validate or get_pricing.

Details

Idempotency

Send an Idempotency-Key header (or idempotency_key) on every order. A retry with the same key and body returns the original order (200, idempotent_replay: true); a different body is a 422, a retry still in flight is a 409.

Details

Test mode

pl_test_ keys validate and price exactly like live keys but never create, charge or send anything: orders come back with test: true.

Details

Agent connect

An assistant without a key calls POST /api/v1/agent/connect (or the connect_account tool); the owner approves by email; the assistant polls for the key, which is returned once.

Details

Balance

GET /api/v1/balance reads the prepaid balance; POST /api/v1/balance/topup returns a checkout link to add funds. Paying with payment.method "balance" waives the small-order handling fee.

Details

MCP server — for AI agents

A remote Model Context Protocol server at https://www.premierletters.com/api/mcp. Quoting, listing handwriting styles, verifying an address and connecting an account work with no key; previewing and creating an order need your API key as a bearer token. Stateless Streamable HTTP — no session setup required.

Add to Claude

  1. claude.ai → Settings → Connectors
  2. Add custom connector
  3. URL: https://www.premierletters.com/api/mcp
  4. Paste your API key as the bearer token

Add to ChatGPT

  1. Settings → Connectors (developer mode)
  2. Add MCP server
  3. URL: https://www.premierletters.com/api/mcp
  4. Provide your API key when prompted for auth
Generic MCP client config
{
  "mcpServers": {
    "premier-letters": {
      "url": "https://www.premierletters.com/api/mcp",
      "headers": { "Authorization": "Bearer pl_live_xxxxx" }
    }
  }
}

Example prompts

  • Send a handwritten thank-you to Jane Doe at 123 Main St, Austin, TX 78701.
  • How much would it cost to mail 50 postcards on premium paper?
  • Preview what this letter will look like in the Classic style before I order it.
  • Check the status of my last Premier Letters order.

MCP tools

connect_account

Get a Premier Letters API key without the user copying one by hand. Pass the user's email and your name; we email them a link to approve (they can sign up from it if they have no account). Then call check_connection with the returned request_id and poll_secret every 10-30 seconds until it returns the api_key (returned once). Show the returned user_code to the user so they can match it on the approval page. No account or key needed to call this.

No key required
check_connection

Check whether the user approved a connect_account request. Returns status pending, denied, expired or claimed, or, exactly once, status approved with the api_key. Poll every 10-30 seconds.

No key required
get_pricing

Get a live price quote for a Premier Letters order. Pass char_count (or letter_count for a rough estimate) plus optional mailing_option and paper_type to get a per-piece and total price, in cents. No account needed. Orders under 5 pieces carry a $0.99 per-piece handling fee (included in total_cents), waived when paid from a prepaid balance. Pass output_mode (printed_bw / printed_color) to quote a printed letter body instead of a pen-written one, and envelope_output_mode to quote a printed envelope.

No key required
list_handwriting_styles

List available handwriting styles (fonts) for a letter order. Use the returned "id" as options.handwriting_style / handwriting_style when creating an order or previewing.

No key required
list_templates

List the authenticated user's saved letter templates.

API key required
verify_address

Verify and standardize a US mailing address via USPS. Use before create_order to catch typos and get the USPS-standardized form.

No key required
preview_letter

Render a preview of a handwritten letter (as an SVG image) and get its price, before creating an order. Does not save anything.

API key required
create_order

Create and pay for a Premier Letters order — a real, handwritten letter mailed via USPS. Requires a Premier Letters API key. Use get_pricing or preview_letter first to confirm the price. For payment, "card_on_file" charges the caller's saved card immediately, "balance" pays from the prepaid account balance (no small-order handling fee; fails with insufficient_balance when short), or "checkout_session" returns a checkout_url for the human to complete payment in a browser. Envelope return address: an explicit no_return_address_ack: true always wins; otherwise a supplied return_address, else the account default. With neither address, set no_return_address_ack: true to send without one.

API key required
get_order_status

Get an order's status, delivery/tracking summary, and per-recipient mail status.

API key required
list_orders

List the authenticated user's recent orders.

API key required
get_balance

Get the authenticated account's prepaid balance (balance_cents) and the top-up rules: minimum and maximum top-up, bonus tiers and suggested amounts. Orders paid with payment.method "balance" skip the small-order handling fee. Use create_topup_link to add funds.

API key required
create_topup_link

Create a Stripe Checkout link that adds prepaid credit (plus any bonus tier) to the authenticated account. Give checkout_url to the human to pay in a browser; the balance updates once they pay (check with get_balance). amount_cents must be a whole number between min_cents and max_cents from get_balance.

API key required

More ways to connect