PostalForm Machine Order
Use this workflow when an agent needs to send real postal mail (a physical print-and-mail order) reliably on the first attempt.
Workflow
1. Collect inputs and choose address strategy
Require these inputs:
buyer_name,buyer_emailsender_name,recipient_name- PDF source (
upload_token,{ download_url, file_id }, data URL, or allowedhttpsURL) - Mailing options (
double_sided,color,mail_class,certified)
For each party (sender, recipient), choose exactly one strategy:
- Manual address:
*_address_type: "Manual"+*_address_manual - Loqate address:
*_address_type: "Address"+*_address_id+*_address_text
Do not mix manual + Loqate for the same party.
2. Build payload with strict idempotency
Generate a UUID request_id once and keep payload bytes stable across retries.
Set buyer_email every time (required for Stripe receipt routing).
For manual addresses:
- Include
line1,city,state,zip - Include
line2only when it has a non-empty string value - Omit optional fields instead of sending
null
Use the tested template in references/payload_templates.md.
3. Preflight with validate endpoint (recommended)
Call:
POST https://postalform.com/api/machine/orders/validate
If response is 200, confirm:
quote.page_countmatches expected page countquote.price_usdand options are acceptable
If response is 422, fix payload before paying.
4. Create order and settle x402 payment
Endpoint:
POST https://postalform.com/api/machine/orders
Flow:
- Send order payload without payment header.
- Receive
402withPAYMENT-REQUIRED. - Create payment using your wallet stack on the requested network.
- Retry the exact same request body with
PAYMENT-SIGNATURE. - Expect
202and settlement metadata.
Payment client options:
purlCLI (fastest path when available)- Any x402-compliant client (
@x402/core,@x402/evm, or equivalent custom signer flow)
If using purl:
- Prefer wallet alias/keystore over raw private keys
- Use
--passwordfrom secure runtime input - Set a protective
--max-amount - Match
--networktoPAYMENT-REQUIREDnetwork
5. Poll order status until post-payment completion
Call:
GET https://postalform.com/api/machine/orders/:request_id
Treat this as complete when:
is_paid = truecurrent_stephas advanced through processing (commonly toemail_sent)order_complete_urlis a real URL
Handle transitional state:
status: "settled_pending_webhook"can persist briefly after on-chain settlement- Continue polling with backoff; do not resubmit a changed payload under the same
request_id
First-Pass Reliability Rules
Required invariants
- Keep
request_idconstant for retries of the same logical order. - Keep payload unchanged when retrying after
402. - Send
buyer_emailalways. - Match payment network to
PAYMENT-REQUIRED; do not hardcode network. - Use only valid US addresses and one address strategy per party.
- Verify page count and quoted price before payment.
Observed failure modes and prevention
422 invalid_typeon manualline2:- Cause: empty optional fields normalized as
null. - Prevent: omit
line2unless non-empty string.
- Cause: empty optional fields normalized as
- Delay after successful payment (
settled_pending_webhook):- Cause: settlement acknowledged before webhook reconciliation completes.
- Prevent: poll for up to several minutes with retry/backoff.
- Occasional non-JSON/transient server response during polling:
- Cause: temporary upstream/render errors.
- Prevent: parse defensively; if response is non-JSON or
5xx, retry without changingrequest_idor payload.
409 request_id_mismatch:- Cause: same
request_idreused with modified payload. - Prevent: generate a new UUID for changed orders; reuse ID only for exact retries.
- Cause: same
Security Rules
- Avoid printing wallet passwords, private keys, or sensitive env vars in logs.
- Prefer encrypted keystore wallets over raw private keys when tooling supports both.
- Use a payment cap (
max amount) to avoid accidental overpayment.
Operator Output
Return these values after execution:
request_id/order_id- price/quote summary (including
page_count) - payment settlement details (
network,pay_to,settlement_tx,settled_at) - latest status (
is_paid,current_step) order_complete_urlwhen available
Reference examples and command snippets:
references/payload_templates.md