LetterAgent API docs


Note: LetterAgent is in private testing. The hosted API base URL is assigned to testers — there are no public api. or mcp. subdomains yet. Examples below use https://<your-assigned-host> as a placeholder.

Basics


Endpoints

Method & pathWhat it does
POST /v1/quotesExact per-letter quote. Retail is always 2× the underlying print + postage cost.
POST /v1/jobsCreate a letter job from a quote. Returns the job and its one-tap Stripe Checkout URL.
POST /v1/webhooks/stripeStripe webhook. On checkout.session.completed the job is fulfilled (the letter is created with the print partner).
GET /v1/jobs/{job_id}Job status, amount, and live mail status.
GET /v1/letters/{letter_id}Raw print-partner letter record.

1. Quote a letter

POST /v1/quotes
Content-Type: application/json

{ "country": "CA", "color": false, "pages": 1 }

Response 201:

{
  "quote_id": "q_fa6f8c0034374ea4",
  "currency": "CAD",
  "country": "CA",
  "color": false,
  "pages": 1,
  "registered": false,
  "amount_cents": 615
}

country is US or CA; pages is an integer ≥ 1. Set registered to true for registered mail (US: certified with tracking; CA: registered with signature). Quote the exact amount_cents to the user and get explicit approval before creating the job. Published retail prices: US B&W $2.12, US colour $2.44, +$0.20/+$0.40 per extra page (USD), US registered B&W $10.40; Canada B&W C$6.15, Canada colour C$6.44, +C$0.58/+C$0.87 per extra page (CAD), Canada registered B&W C$51.12.


2. Create a job (after the user approves the price)

POST /v1/jobs
Content-Type: application/json

{
  "quote_id": "q_fa6f8c0034374ea4",
  "idempotency_key": "550e8400-e29b-41d4-a716-446655440000",
  "letter": {
    "to": {
      "firstName": "Jane", "lastName": "Doe",
      "addressLine1": "123 Main St", "city": "Toronto",
      "provinceOrState": "ON", "postalOrZip": "M4B 1B3",
      "countryCode": "CA"
    },
    "from": {
      "companyName": "Sam Smith",
      "addressLine1": "456 Oak Ave", "city": "Markham",
      "provinceOrState": "ON", "postalOrZip": "L6B 0P6",
      "countryCode": "CA"
    },
    "html": "<html><body><p>Dear landlord, please fix the tap. — Sam</p></body></html>"
  }
}

Response 201 (or 200 with the identical body if the idempotency_key was already used — no duplicate job, no second charge):

{
  "job_id": "job_8f42k1ab9c0d2e3f",
  "status": "awaiting_payment",
  "amount_cents": 615,
  "amount": "C$6.15",
  "currency": "CAD",
  "checkout_url": "https://checkout.stripe.com/c/...",
  "payment_mode": "real"
}

to/from require addressLine1, city, and countryCode (US/CA). Send html or pdf_url. The quote's country must match the destination country. Hand checkout_url to the user — one tap, one card payment, one letter.


3. Payment webhook

Point Stripe at POST /v1/webhooks/stripe. On checkout.session.completed the server marks the job paid and creates the letter with the print partner — fulfilment starts only after payment succeeds. Duplicate deliveries return the already-created letter instead of mailing twice.


4. Check status

GET /v1/jobs/job_8f42k1ab9c0d2e3f

{
  "job_id": "job_8f42k1ab9c0d2e3f",
  "status": "fulfilled",
  "amount_cents": 615,
  "amount": "C$6.15",
  "currency": "CAD",
  "letter_id": "letter_v3cwk7Nwm13XRGHwkSzSsE",
  "mail_status": "ready — in the print queue",
  "error": null
}

Job status: awaiting_paymentpaidfulfilled (or failed). mail_status maps the print partner's state: ready (in the print queue), printing, processed for delivery, completed, cancelled. completed means most likely delivered — never report it as confirmed delivery.


5. Errors

All errors look like this:

{ "error": "quote is for US but destination is CA; request a new quote" }
HTTPMeaning
400Bad request — fix the fields named in the message and retry.
401Webhook signature check failed (real-Stripe mode only).
404Unknown job or letter id.
409Job is in a state that can't be fulfilled (e.g. already failed).
502The print partner call failed; the job is marked failed with details.

6. MCP-shaped tools

Prefer tools over HTTP? mcp-tools.json defines quote_letter, create_letter_job, and get_job_status with the exact shapes above. The hosted MCP transport is assigned during private testing.


Home · Contact: hello@getletteragent.com · No cookies. No tracking.