unopost

x402 API

Post a letter from code, pay in USDC

Apps and AI agents can post a letter anywhere in Australia and pay per letter in USDC over x402. No account, API key or subscription: just a wallet and an HTTP client.

20 USDCper letter by Express Post

10 USDCper letter by regular post

Up to 12 pages, then 0.50 USDC a page, GST included. Paid in USDC on Base, gas covered.

Posting in bulk? Business pricing from 2 USDC a letter.

See the APIOpenAPI spec

Why post letters over x402?

The same letter as the website, paid for over HTTP.

No account or API key

Nothing to sign up for. Your code creates a letter, gets a price and pays with a signed USDC payment.

A fixed price per letter

20 USDC by Express Post or 10 USDC by regular post covers printing, the envelope, postage and tracking for up to 12 pages, GST included. Gas is on us.

The same letter as the website

Printed as uploaded on 80gsm A4, tracked, and posted the same business day if paid by 2:30pm Sydney time.

Refunded if it can't be posted

If we can't post it, we refund the paying wallet in full, in USDC. Letters cancelled for breaking the acceptable use policy in our terms aren't refunded.

Who it's for

  • AI agents

    An agent handling a bond dispute, insurance claim or council complaint can post the letter itself and pay from its own wallet.

  • Apps and scripts

    Property management, legal and billing software that posts letters, without a merchant account or monthly plan.

Pricing

ItemPrice
Express Post letter: up to 12 pages and flat A4 envelope20 USDC
Regular post letter: up to 12 pages and flat A4 envelope10 USDC
Each page after 120.50 USDC
TrackingFree
Double-sided printingFree
Folded to fit a letterbox (up to 10 pages)Free
Signature on delivery (Express Post only)Free
Network fee (gas)Covered

Prices are in USDC on Base. The price is set once your document is laid out on A4; quotes last 7 days.

Business bulk API

Business pricing starts from 2 USDC a letter. Email support@unopost.com.au for details and a bizKey to send with each letter.

How it works

Endpoints are relative to https://unopost.com.au. Requests and responses are JSON; errors are {"error": "..."}. Full reference: the OpenAPI spec.

  1. Create a letter

    POST the file name, the recipient's address and your return address. You get a jobId, a signed uploadUrl, and URLs to check and pay for the letter.

    Request
    curl -X POST https://unopost.com.au/api/x402 \
      -H "Content-Type: application/json" \
      -d '{
      "fileName": "notice.pdf",
      "recipient": {
        "name": "Ruth Mitchell",
        "line1": "7 High Street",
        "suburb": "Echuca",
        "state": "VIC",
        "postcode": "3564"
      },
      "sender": {
        "name": "Sam Nguyen",
        "company": "Nguyen Property",
        "line1": "14 Carnarvon Street",
        "suburb": "Broome",
        "state": "WA",
        "postcode": "6725"
      },
      "service": "express",
      "signature": true
    }'
    Response 200
    {
      "jobId": "019d7a7f-a183-752d-9b3b-11511179033b",
      "uploadUrl": "https://unopost.com.au/uploads/019d7a7f-a183-752d-9b3b-11511179033b/notice.pdf?Expires=...&Signature=...&Key-Pair-Id=...",
      "statusUrl": "/api/x402/019d7a7f-a183-752d-9b3b-11511179033b",
      "sendUrl": "/api/x402/019d7a7f-a183-752d-9b3b-11511179033b/send",
      "status": "awaiting_upload"
    }

    Request body

    fileNamestring · required
    The file name with its extension: .pdf, .doc, .docx, .jpg, .jpeg or .png.
    recipientAddress · required
    The address to post the letter to.
    senderAddress · required
    Your return address, printed on the envelope so undeliverable mail comes back to you.
    servicestring · optional
    "express" for Express Post (the default) or "regular" for regular post.
    duplexboolean · optional
    Print double-sided. Defaults to false. Statutory declarations are always single-sided.
    foldboolean · optional
    Fold to fit a letterbox. Documents over 10 pages are posted flat.
    signatureboolean · optional
    Signature on delivery. Express Post only: it's a 400 with regular post.
    bizKeystring · optional
    Your business key, for bulk pricing. The quote shows your price. An unknown key is a 400.

    Address

    The recipient must be in Australia. The return address can be anywhere: set its country, and its state and postcode become optional. Each line can be up to 40 characters.

    namestring · optional
    The person's full name.
    companystring · optional
    A business or organisation.
    line1string · required
    The street address, or a PO Box such as "PO Box 123".
    line2string · optional
    A second address line.
    suburbstring · required
    The suburb or town.
    statestring · required
    ACT, NSW, NT, QLD, SA, TAS, VIC or WA.
    postcodestring · required
    Four digits, within the given state.
    countrystring · optional
    Return address only. Leave it out for Australia.
  2. Upload the document

    PUT the raw file bytes to uploadUrl within 15 minutes. Up to 50 MB and 50 pages. Layout on A4 starts as soon as the upload lands; there's nothing else to call.

    Request
    curl -X PUT "$UPLOAD_URL" \
      -H "Content-Type: application/pdf" \
      --data-binary @notice.pdf
  3. Wait for the price

    Poll every few seconds until status is ready_to_send. The response then has the page count, the price in payment, the sendUrl, and a previewUrl for the print-ready PDF to check before paying.

    Request
    curl https://unopost.com.au/api/x402/$JOB_ID
    Response 200
    {
      "jobId": "019d7a7f-a183-752d-9b3b-11511179033b",
      "service": "express",
      "duplex": false,
      "fold": false,
      "signature": true,
      "recipient": {
        "name": "Ruth Mitchell",
        "line1": "7 High Street",
        "suburb": "Echuca",
        "state": "VIC",
        "postcode": "3564"
      },
      "sender": {
        "name": "Sam Nguyen",
        "company": "Nguyen Property",
        "line1": "14 Carnarvon Street",
        "suburb": "Broome",
        "state": "WA",
        "postcode": "6725"
      },
      "pageCount": 3,
      "status": "ready_to_send",
      "previewUrl": "/preview/019d7a7f-a183-752d-9b3b-11511179033b/notice.pdf?Expires=...&Signature=...&Key-Pair-Id=...",
      "payment": {
        "scheme": "exact",
        "network": "eip155:8453",
        "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
        "amountAtomic": "20000000",
        "amountDisplay": "20 USDC",
        "payTo": "0x1111111111111111111111111111111111111111",
        "expiresAt": "2026-09-25T02:15:00Z"
      },
      "sendUrl": "/api/x402/019d7a7f-a183-752d-9b3b-11511179033b/send"
    }

    fold and duplex may now be false: documents over 10 pages are posted flat, and statutory declarations are always printed single-sided.

  4. Pay and post

    POST to sendUrl without a payment. The response is 402 Payment Required, with the payment requirements base64-encoded in the PAYMENT-REQUIRED header.

    Request
    curl -i -X POST https://unopost.com.au/api/x402/$JOB_ID/send
    Response 402
    HTTP/2 402
    payment-required: eyJ4NDAyVmVyc2lvbiI6Mi...
    
    {
      "error": "payment required"
    }
    PAYMENT-REQUIRED header, base64-decoded
    {
      "x402Version": 2,
      "accepts": [
        {
          "scheme": "exact",
          "network": "eip155:8453",
          "asset": "0x833589fCD6eDb6E08f4c7C32D4f71b54bdA02913",
          "amount": "20000000",
          "payTo": "0x1111111111111111111111111111111111111111",
          "maxTimeoutSeconds": 300,
          "extra": {
            "name": "USD Coin",
            "version": "2"
          }
        }
      ]
    }

    Sign the payment as the x402 protocol describes (or let an x402 client library do it) and resend the request with the payload in a PAYMENT-SIGNATURE header. We verify and settle it, and the letter goes to print. The PAYMENT-RESPONSE header has the settlement.

    Request
    curl -i -X POST https://unopost.com.au/api/x402/$JOB_ID/send \
      -H "PAYMENT-SIGNATURE: $PAYMENT_SIGNATURE"
    Response 202
    HTTP/2 202
    payment-response: eyJzdWNjZXNzIjp0cnVlLC...
    
    {
      "jobId": "019d7a7f-a183-752d-9b3b-11511179033b",
      "status": "sending"
    }

    Got 409 with job not ready to send just after ready_to_send? Wait a moment and retry. Calling again after paying returns the status without charging twice.

  5. Follow the letter

    Keep polling, less often, until the letter is posted, then delivered. There are no emails; every update appears in the status.

    Request
    curl https://unopost.com.au/api/x402/$JOB_ID
    Response 200
    {
      "jobId": "019d7a7f-a183-752d-9b3b-11511179033b",
      "service": "express",
      "duplex": false,
      "fold": false,
      "signature": true,
      "recipient": {
        "name": "Ruth Mitchell",
        "line1": "7 High Street",
        "suburb": "Echuca",
        "state": "VIC",
        "postcode": "3564"
      },
      "sender": {
        "name": "Sam Nguyen",
        "company": "Nguyen Property",
        "line1": "14 Carnarvon Street",
        "suburb": "Broome",
        "state": "WA",
        "postcode": "6725"
      },
      "pageCount": 3,
      "status": "posted",
      "providerReference": "LTR-8F3A21C9"
    }

Statuses

awaiting_upload
Waiting for the file.
processing
Laying the document out on A4 and pricing it.
ready_to_send
Priced and waiting for payment. The quote lasts 7 days.
sending
Paid, and with our print partner.
retrying
Our print partner hit a problem; we're retrying automatically.
posted
Printed and lodged with Australia Post.
delivered
Delivered by Australia Post. The document was deleted at dispatch.
failed
Not posted; the reason is in error, such as a quote that expired unpaid. A paid letter that can't be posted is refunded in full.
refunded
The payment has gone back to the wallet that paid for it.

Errors

400
Invalid request: for example a missing field, unsupported file type, address line over 40 characters, postcode outside the state, signature on delivery with regular post, or an unknown bizKey.
402
Payment is required, or the payment couldn't be verified or settled. error says why.
404
There's no letter with that jobId.
409
job not ready to send: wait for ready_to_send and try again. quote expired: create the letter again.

Frequently asked questions

What is x402?

An open protocol for paying over HTTP. The server replies 402 Payment Required with a price; the client signs a stablecoin payment and resends the request. No account, card or invoice.

What do I need?

A wallet on Base with enough USDC, and an HTTP client. No ETH needed for gas: the payment is a signed USDC transfer authorisation, and we cover the network fee.

How much does a letter cost?

20 USDC by Express Post or 10 USDC by regular post for up to 12 pages, then 0.50 USDC a page, GST included. Tracking, double-sided printing and folding are free, as is signature on delivery with Express Post. The status response shows the exact price before you pay.

Can I check the letter before paying?

Yes. Once it's ready to send, previewUrl is the print-ready PDF, laid out on A4 exactly as it will be printed. Nothing is charged until you pay.

When is it posted, and how long does it take to arrive?

Letters paid by 2:30pm Sydney time on a business day are posted that day; later ones, the next business day. Express Post usually arrives the next business day within the Express Post network, regular post in 3 to 7 business days.

What if the letter can't be posted?

Its status changes to failed and we refund the full amount in USDC to the paying wallet, unless we cancelled it for breaking the acceptable use policy in our terms. For anything else, email support@unopost.com.au with the jobId.

What happens to my document?

It's encrypted in transit and permanently deleted, with its print-ready copy, once the letter is lodged with Australia Post. If a letter isn't paid for or can't be posted, it's deleted after 14 days.

Where can letters go?

Any address in Australia, including PO Boxes, in every state and territory. The API doesn't post overseas.

Who's responsible for what an agent sends?

You are. Every letter paid for from your wallet is yours, including one an agent wrote and sent on your instructions, and you need the right to send what's in it. Our terms list what can't go in the post: impersonation, harassment, scams, unsolicited advertising in bulk, and anything that breaches a court order. We cancel letters that break those rules, without a refund. If you post on someone else's behalf, you're responsible for their document as if it were yours.