LettrLabs API

Order of operations

The end‑to‑end path to send your first order — find a template, create the order, add recipients, and check out.

This walkthrough puts the API calls in the order you actually make them: start from a template, create an order, attach recipients, then confirm and pay. Each step links to the full reference, where you can fire the request live with your own key.

New here? Skim Authentication & API keys first — every call below sends your key in the X-API-KEY header.

1. Get a template ID

Orders are generated from a template you design in the LettrLabs app (handwritten cards, printed mail, and so on). Open the template in the app; its numeric template ID is the templateId you pass when creating an order. You can also list your account's templates — and read their IDs — with GET /v1/templates.

2. Create the order

Create the order with POST /v1/order. The only required field is templateId; recipients and mailing options can be set now or added in the next step.

curl -X POST https://app.lettrlabs.com/api/v1/order \
  -H "X-API-KEY: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '{ "templateId": 12345 }'

Keep the returned order ID — every later step uses it.

3. Add recipients

Attach (or replace) the order's recipients with PUT /v1/order/{id}/recipients. Review what's currently attached with GET /v1/order/{id}/recipients.

curl -X PUT https://app.lettrlabs.com/api/v1/order/ORDER_ID/recipients \
  -H "X-API-KEY: your_api_key_here" \
  -H "Content-Type: application/json" \
  -d '[ { /* see the reference for the recipient shape */ } ]'

4. Preview a proof (optional)

Before you pay, pull a rendered proof with GET /v1/order/{id}/proof to confirm the mail looks right.

5. Check out

Confirm and pay for the order with POST /v1/order/{id}/checkout. Until you check out, the order is a draft and nothing mails.

curl -X POST https://app.lettrlabs.com/api/v1/order/ORDER_ID/checkout \
  -H "X-API-KEY: your_api_key_here"

The 200 means accepted, not charged

Payment settles asynchronously, so a 200 tells you the checkout was accepted — not that the order has been paid. The response tells you how to wait for the rest:

FieldWhat it tells you
orderStatusthe order's state as the call returns — normally Payment Needed, meaning accepted and settling
pollAfterSecondshow long to wait before your first status read; reading sooner cannot tell you anything new
settlementExpectedWithinSecondswhen settlement is expected to have reached a terminal state

Poll GET /v1/order filtered to your order id and watch for paidDate to be set, or for status to become Paid. A return to Draft means the payment failed and you can edit and check out again. While the order is Payment Needed it is not editable — recipient changes, deletion, and a second checkout all return 400 until it settles.

Size your polling from settlementExpectedWithinSeconds rather than a bound of your own, and treat it as an expectation rather than a guarantee: if it elapses while the order is still Payment Needed, the order is not lost and no second charge is pending. Never retry a checkout that returned 200 — the charge is already in flight, and a second checkout charges again. Ask us to confirm settlement instead.

After it mails

Re‑sending POST /v1/order creates a new order every time — there is no automatic de‑duplication. See the idempotency note in Creating an Order before adding retries.

On this page