SkillHub

postalform-agent-mailing

v1.0.0

Send real postal mail through PostalForm using machine payments: prepare/validate print-and-mail payloads, submit `POST /api/machine/orders`, settle x402 payment with any compatible wallet client (purl or custom), and poll fulfillment through completion. Use when an agent must autonomously mail a re...

Sourced from ClawHub, Authored by Gabriel Garrett

Installation

Please help me install the skill `postalform-agent-mailing` from SkillHub official store. npx skills add ggaabe/postalform-agent-mailing

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_email - sender_name, recipient_name - PDF source (upload_token, { download_url, file_id }, data URL, or allowed https URL) - 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 line2 only when it has a non-empty string value - Omit optional fields instead of sending null

Use the tested template in references/payload_templates.md.

Call: - POST https://postalform.com/api/machine/orders/validate

If response is 200, confirm: - quote.page_count matches expected page count - quote.price_usd and 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: 1. Send order payload without payment header. 2. Receive 402 with PAYMENT-REQUIRED. 3. Create payment using your wallet stack on the requested network. 4. Retry the exact same request body with PAYMENT-SIGNATURE. 5. Expect 202 and settlement metadata.

Payment client options: - purl CLI (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 --password from secure runtime input - Set a protective --max-amount - Match --network to PAYMENT-REQUIRED network

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 = true - current_step has advanced through processing (commonly to email_sent) - order_complete_url is 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_id constant for retries of the same logical order.
  • Keep payload unchanged when retrying after 402.
  • Send buyer_email always.
  • 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_type on manual line2:
  • Cause: empty optional fields normalized as null.
  • Prevent: omit line2 unless non-empty string.
  • 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 changing request_id or payload.
  • 409 request_id_mismatch:
  • Cause: same request_id reused with modified payload.
  • Prevent: generate a new UUID for changed orders; reuse ID only for exact retries.

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_url when available

Reference examples and command snippets: - references/payload_templates.md