Ordering letters through ModernMail
- Upload each document with
upload_document (a public URL or base64 of a PDF or Word file). Note the returned file id and pageCount.
- Quote with
quote_order: one entry per recipient with their address, the postage service, print options and the file ids. The quote returns expectedTotalPence and whether the account's credit covers it.
- Confirm with the user before spending: show the total, recipients and service. Orders are paid from prepaid credit. They can be cancelled with
cancel_order for a full refund only while nothing has been started on them (usually the same day, before printing); after that the user asks support.
- Create with
create_order, passing the same letters, expectedTotalPence from the quote and a fresh idempotencyKey (a UUID) you keep for retries. The order is printed and posted by ModernMail; use get_order to follow its status and tracking.
To post on a later day, pass postOn to create_order: a UK working day (Mon–Fri, not a bank holiday) in YYYY-MM-DD, from tomorrow up to 12 months ahead. The order is paid now and held in the account until that morning; until then the user can change the day or cancel it for a full refund from their account. Confirm the day with the user before creating the order. A weekend or bank holiday is refused with post_on_invalid and details.nextWorkingDay.
To have a letter arrive by a date instead, pass deliverBy (YYYY-MM-DD, a day Royal Mail delivers on: Mon–Sat, not a bank holiday) in place of postOn. ModernMail works back from Royal Mail's usual aim for each letter's postage service to the last working day that still makes it and holds the order until then; the response's postOn is that day. Only services that can reach the date are accepted: a 1st Class, Tracked 24 or Special Delivery letter can arrive the next working day, 2nd Class and Tracked 48 the day after next (1st Class, 1st Class Signed For, Tracked 24 and Tracked 48 are delivered on Saturdays too; 2nd Class and Special Delivery are not). A service that can't make it is refused with deliver_by_unreachable; details.services lists each service's earliest date and details.suggestedDeliverBy the first date they all meet, so either move the date or change the service. These are Royal Mail's aims, not guarantees; Special Delivery is the guaranteed service.
Addresses: UK recipients need a valid postcode and recipientCountry: "GB" (the default); non-UK recipients must use postageType: "international_standard" with their ISO country code. When the key has the addresses:validate scope, run validate_address on each UK recipient before quoting: use a corrected address as returned, and ask the user to choose when it is unmatched. It is a metered lookup, so once per address, not in a loop. Postage services and prices are in get_pricing. Amounts are integer pence.
If create_order fails with insufficient_credit, tell the user the shortfall and give them the top-up link; do not retry until they have added credit.
A key starting mm_test_ is a sandbox key: every tool works the same, but orders are simulated (livemode: false), nothing is charged, printed or posted, and the credit shown is a daily sandbox allowance. Tell the user when you are in the sandbox.