PostalForm MCP
About
Mail real letters from agents: PDF → checkout → status.
Details
- Author
- Unknown
- Categories
- Productivity, Other, API, Automation
Jump to
Mail real letters from agents: PDF → checkout → status.
Mail API and Remote MCP Server for AI Agents
PostalForm is a mail API and remote MCP server for turning PDFs, letters, forms, and agent output into real physical postal mail. Developers can create reviewable mail drafts, hosted checkout sessions, direct MPP/x402 machine orders, and fulfillment-status lookups without building print, envelope, postage, or carrier-handoff infrastructure.
Quick answer: can developers send postal mail through an API?
Yes. PostalForm lets developers send postal mail through API and MCP workflows. Use hosted-checkout draft tools when a human should review the PDF, addresses, mailing options, and price before payment. Use direct MPP or x402 machine-payment flows only for autonomous runtimes with explicit owner approval, spending limits, and idempotent request IDs.
Use this table when evaluating PostalForm for an MCP registry, agent directory, API catalog, connector review, or developer-tool listing.
PostalForm is a remote MCP server and physical mail API for creating reviewable print-and-mail drafts from PDFs, letters, and forms, with hosted checkout, fulfillment status, and approved MPP/x402 machine-payment flows.
Which integration surface should you use?
Use these canonical URLs when listing PostalForm in MCP directories, connector catalogs, or agent registries:
- Remote MCP endpoint:https://postalform.com/mcp
- A2A Agent Card:https://postalform.com/.well-known/agent-card.json
- A2A JSON-RPC discovery bridge:https://postalform.com/a2a
- MCP server card:https://postalform.com/.well-known/mcp/server-card.json
- MCP compatibility manifest:https://postalform.com/.well-known/mcp.json
- MCP Registry server manifest:https://postalform.com/.well-known/mcp/server.json
- Agent skill:https://postalform.com/skill.md
- LLM overview:https://postalform.com/llms.txt
- Full LLM content dump:https://postalform.com/llms-full.txt
- Open Knowledge Format index:https://postalform.com/okf/index.md
- APIs.json index:https://postalform.com/apis.json
- API catalog:https://postalform.com/.well-known/api-catalog
- API specification:https://postalform.com/openapi.json
- Agent guide:https://postalform.com/agents
- AI instructions:https://postalform.com/ai
The hosted MCP server is best for clients that can connect to a remote streamable HTTP MCP endpoint. Usepostalform.create_order_draft,postalform.create_letter_order_draft, andpostalform.create_form_order_draftwhen a human should review and pay in hosted checkout. Usepostalform.create_machine_orderonly when an authorized autonomous runtime should answer an MPP or x402 payment challenge directly.
For the design pattern behind this split, seemaking physical mail callable from AI agents.
PostalForm is ready for clients that can connect to remote MCP servers over streamable HTTP. The same endpoint is used by ChatGPT custom connector-style flows, OpenAI Responses API MCP tools, Gemini SDK MCP sessions, Gemini CLI, Claude, Claude Code, Codex, Cursor, Windsurf, Cline, Replit, OpenClaw, Hermes, n8n, LangChain, and similar MCP clients.
For ChatGPT or OpenAI Responses API integrations, configure PostalForm as a remote MCP server:
{ "type": "mcp", "server_label": "postalform", "server_description": "Create real PostalForm mail drafts, hosted checkout sessions, machine-payment mail orders, and order status lookups.", "server_url": "https://postalform.com/mcp", "require_approval": "always" }
For Gemini CLI, add PostalForm as an HTTP MCP server:
gemini mcp add --transport http postalform https://postalform.com/mcp
For Gemini SDKs, create an MCP client session against the PostalForm endpoint and pass the session tools into Gemini's tool-calling integration. In web-chat clients and user-facing assistant flows, prefer hosted checkout so the user can review the PDF, addresses, price, and mailing options before paying.
PostalForm also supports the UCP Checkout capability for platforms that integrate via the UCP MCP binding.
- Discovery profile:https://postalform.com/.well-known/ucp
- UCP MCP endpoint:https://postalform.com/ucp/mcp
- Capability: dev.ucp.shopping.checkout (version 2026-01-11)
- Tools: create_checkout, get_checkout, update_checkout, complete_checkout, cancel_checkout
UCP checkout sessions are dynamically priced based on PDF page count and print options. PostalForm expects the PDF and address data inmetadata.postalform(pdf can be{ download_url, file_id },{ upload_token }, a data URL, or an allowlisted https URL). UCP tool calls must include a platform profile in_meta.ucp.profile.
Note: UCP currently supports PDF-based checkouts with Loqate Address IDs (_address_type="Address") only. For manual addresses, letter text, and workflow forms, use the PostalForm MCP tools on/mcp.
{ "name": "create_checkout", "arguments": { "_meta": { "ucp": { "profile": "https://platform.example/profiles/v2026-01/shopping-agent.json" } }, "currency": "USD", "line_items": [{ "item": { "id": "postalform_mail_pdf_bw_double" }, "quantity": 1 }], "payment": {}, "metadata": { "postalform": { "pdf": { "download_url": "https://example.oaiusercontent.com/file.pdf", "file_id": "file_abc123" }, "file_name": "letter.pdf", "sender_name": "Sender Example", "sender_address_id": "US|LP|Pz0_Qj4_bGJg|16074807|13_ENG", "sender_address_type": "Address", "sender_address_text": "123 Sender St, Springfield, IL 62701", "recipient_name": "Recipient Example", "recipient_address_id": "US|LP|Pz0_Qj4_bGJg|199825276|99_ENG", "recipient_address_type": "Address", "recipient_address_text": "456 Recipient Ave, Springfield, IL 62701", "double_sided": true, "color": false } } } }
PostalForm supports x402-based machine payments for direct API order creation. The machine payment endpoints are designed for agent runtimes that may not have a PostalForm login or API key: the unpaid create call returns a payment challenge, and the paid retry authorizes the order. Letter payloads can be raw text, HTML, Markdown, or RTF and can include typed or drawn signatures; PostalForm renders the PDF server-side and may return a signed preview URL before payment.
For a crawler-friendly overview of the x402 physical-mail flow, directory fields, and safety defaults, seex402 physical mail API.
- Create/pay endpoint:POST https://postalform.com/api/machine/orders
- Validate/quote endpoint (no payment side effects):POST https://postalform.com/api/machine/orders/validate
- Status endpoint:GET https://postalform.com/api/machine/orders/:id
- Flow: unpaid request returns402+PAYMENT-REQUIRED, client pays and retries withPAYMENT-SIGNATURE, server returns202+PAYMENT-RESPONSE;settled_pending_webhookmeans Stripe is still verifying the settlement, so poll the status endpoint rather than paying again
Required request fields forPOST /api/machine/orders:
- request_id(UUID)
- buyer_name
- buyer_email(required; set on Stripe PaymentIntent asreceipt_email)
- exactly one document source:
- pdf(recommended canonical format:{ "upload_token": "..." }; also accepts{ download_url, file_id }, data URL, or allowlisted https URL)
- letter(raw string or object withformatset totext,html,markdown, orrtf; optionalsignatureas a string or{ mode: "typed" | "drawn", text?, dataUrl?, printDataUrl? }; PostalForm renders the PDF server-side)
- form(single-mailpiece workflow form payload discovered through the machine forms schema endpoints; signature fields accept typed or drawn signature payloads when present; statutory multi-recipient workflows are excluded and remain web-only)
- double_sided(defaulttrue)
- color(defaultfalse)
- mail_class(standard,priority,express)
- certified(defaultfalse)
- certified_return_receipt(defaultfalse; adds a return receipt for US Certified Mail; ignored for PinGen registered mail)
- return_receipt_format(electronicby default, orphysicalfor the mailed PS Form 3811 green card; requirescertified_return_receipt=true)
- restricted_delivery(defaultfalse; requests addressee-only USPS Restricted Delivery and requirescertified_return_receipt=true)
- err_delivery(manualby default, oremailto have PostalForm acquire and email the signed electronic receipt)
- err_email(optional override for automatic delivery; defaults tobuyer_emailwhen omitted)
- signature_required(defaultfalse; requests USPS signature-on-delivery; ignored for postcards or whenmail_class="standard")
- mailpiece_type(letterorpostcard; defaultletter)
- postcard_size(4x6,6x9,11x6; required whenmailpiece_type="postcard")
Postcard machine orders use the same endpoints and payment flow. For postcards, sendpdfas the final composed postcard PDF and setmailpiece_type: "postcard"pluspostcard_size.
- Use a2-page PDF.
- Page 1 is the artwork side.
- Page 2 is the mailing side. You can place backside artwork or a non-address message there, but donotplace sender/recipient names, return or delivery addresses, indicia, or barcode data in the PDF. PostalForm fills the mailing block automatically.
- Match the exact bleed canvas for the selected size. The canonical spec and templates live atpostcard PDF guidelines:
- 4x6 template
- 6x9 template
- 11x6 template
PostalForm normalizes postcard print options server-side to standard mail, full color, double-sided, and no certified/signature add-ons.
- Letter text:postalform.create_letter_order_draft(recommended for ChatGPT apps).
- Workflow forms:postalform.list_forms->postalform.get_form_schema->postalform.create_form_order_draft.
- PDF upload:postalform.create_order_draft(ChatGPT file params,upload_token, data URL, or allowlisted https URL).
- Official ChatGPT or Claude web chat UIs: send the customer tocheckout_url, or usecheckout_sessionfor ChatGPT Instant Checkout.
- Autonomous runtimes such as Codex, Claude Code, OpenClaw, or Hermes: callpostalform.create_machine_order, pay the returned MPP or x402 challenge with Link CLI/Link MCP or an x402 wallet client, then retry the same tool call with the payment credential.
import { Client } from '@modelcontextprotocol/sdk/client/index.js' import { StreamableHTTPClientTransport } from '@modelcontextprotocol/sdk/client/streamableHttp.js' const transport = new StreamableHTTPClientTransport(new URL('https://postalform.com/mcp')) const client = new Client({ name: 'my-agent', version: '1.0.0' }) await client.connect(transport) await client.listTools() const draft = await client.callTool({ name: 'postalform.create_letter_order_draft', arguments: { letter: { title: 'Demand for payment', body: 'Hello...\\n\\nThis is my letter body.\\n\\nSincerely,\\n', signature: 'Sender Example', }, sender_name: 'Sender Example', sender_address_type: 'Manual', sender_address_manual: { line1: '123 Sender St', city: 'Springfield', state: 'IL', zip: '62701', }, recipient_name: 'Recipient Example', recipient_address_type: 'Manual', recipient_address_manual: { line1: '456 Recipient Ave', city: 'Springfield', state: 'IL', zip: '62701', }, }, }) console.log(draft.structuredContent?.checkout_url)
- Usecheckout_urlfrompostalform.create_order_draftto send customers to the hosted PostalForm payment page.
- Best default for browser-chat MCP clients or any flow where a person should review and pay.
- Open the URL in a browser (orwindow.openai.openExternalinside ChatGPT).
- Pollpostalform.get_order_statusto confirm payment and fulfillment.
ChatGPT Instant Checkout (Stripe Agentic Commerce)
- PostalForm returns an ACPcheckout_sessionin the draft response that ChatGPT uses to show Instant Checkout.
- When the buyer confirms, ChatGPT callscomplete_checkoutwith a Stripe Shared Payment Token (spt_...).
- Usewindow.openai.requestCheckout(checkout_session)in your UI.
- Usecheckout_urlas a fallback ifwindow.openai.requestCheckoutis unavailable.
Direct machine payment (agentic MCP clients)
- Usepostalform.create_machine_orderwhen the agent will pay instead of sending a human to hosted checkout.
- First call it withpayment_protocol="mpp"or"x402"and no payment credential.
- For MPP, pay one returnedWWW-Authenticate: Payment ...challenge with Link CLI, the Link MCP server, Tempo, or a card-MPP client such as Visa'smpp-card/client, then retry the same tool arguments withpayment_authorization.
- For x402, pay the returnedPAYMENT-REQUIREDchallenge with an x402-compatible wallet/client, then retry the same tool arguments withpayment_signature.
- Reuse the samerequest_idand order fields on retry.
- postalform.list_forms: List supported single-mailpiece workflow forms available to agents. Coordinated statutory multi-recipient workflows remain web-only.
- postalform.get_form_schema: Fetch a supported single-mailpiece workflow schema (fields, dependencies, attachments). The machine schema caps inline attachment files and reportsattachments_max_total_size_mb(currently 12 MB combined after base64 decoding). May includecheckout_flowmetadata (homeorforms_order) for PostalForm web routing; MCP clients/agents can treat this as informational.
- postalform.create_letter_order_draft: Create a draft order from letter text (server renders a PDF).
- postalform.create_form_order_draft: Create a draft order from a supported single-mailpiece workflow JSON submission; the server fills a form, renders a letter, or assembles required uploaded packet documents according to the discovered schema. Inline workflow attachments are limited to 12 MB combined after base64 decoding even when the browser upload workflow permits larger files.
- postalform.create_pdf_upload: Create a short-lived PDF upload URL +upload_tokenfor agents that cannot pass ChatGPT file params. Upload the PDF, then callpostalform.create_order_draftwithpdf: { upload_token: "..." }.
- postalform.search_addresses: Search mailing address suggestions. Input:query(min 3 chars), optionalcountry_code(defaults toUS), optionalcontainer(for drilling into Container results), optionaltarget. Output: address suggestions with ids/text/type/country. If type is Container, call search again withcontainer=idto get Address results for order drafts.
- postalform.create_order_draft: Create a draft order and receive a checkout URL. Input:pdf(ChatGPT file object{ download_url, file_id }, or{ upload_token }frompostalform.create_pdf_upload, or adata:application/pdf;base64,...URL, or an https URL on an allowlisted host), sender/recipient names, and either Loqate addresses (_address_type="Address"+_address_id) or manual addresses (_address_type="Manual"+_address_manual, with optionalcountryCode). Output:order_id,price_usd,checkout_url,checkout_session.
- postalform.create_machine_order: Create and pay a machine order from a PDF, letter text, or workflow form using direct MPP or x402. Output:payment_requiredchallenge details on the first call, then paid/settled order details after retrying withpayment_authorization(MPP) orpayment_signature(x402). A paid crypto retry can briefly returnsettled_pending_webhook; poll status and do not pay again.
- complete_checkout: Finalize a ChatGPT Instant Checkout session with a payment token. Input:checkout_session_id(orderid),buyer(first_name, last_name optional, email),payment_data.token(Stripe shared payment token,spt...),provider=stripe. Output: checkout session response with status and order permalink.
- postalform.get_order_status: Fetch the latest order status details. Input:order_id. Output:found,is_paid,current_step(for example:payment_received,receiver_address_verified,sender_address_verified,pdf_normalized,letter_created,email_sent,canceled,refunded,abandoned).
- postalform.ping: Health check for the MCP server. Input: none. Output: ping payload for connectivity checks.
{ "name": "postalform.list_forms", "arguments": { "q": "IRS", "limit": 10 } }
{ "name": "postalform.get_form_schema", "arguments": { "slug": "1099-nec" } }
Note: the response may includecheckout_flow. This is workflow metadata for PostalForm web checkout routing and does not change MCP tool-call sequencing.
{ "name": "postalform.search_addresses", "arguments": { "target": "recipient", "query": "123 Main St" } }
{ "structuredContent": { "view": "address_suggestions", "target": "recipient", "query": "123 Main St", "suggestions": [ { "id": "US|LP|Pz0_Qj4_bGJg|16074807|13_ENG", "text": "123 Main St, Springfield, IL 62701", "type": "Address", "description": "" } ] } }
{ "name": "postalform.create_letter_order_draft", "arguments": { "request_id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "letter": { "title": "Payment demand letter", "body": "Hello,\\n\\nThis is the letter body.\\n\\nSincerely,\\n", "signature": "Sender Example" }, "sender_name": "Sender Example", "sender_address_type": "Manual", "sender_address_manual": { "line1": "123 Sender St", "city": "Springfield", "state": "IL", "zip": "62701" }, "recipient_name": "Recipient Example", "recipient_address_type": "Manual", "recipient_address_manual": { "line1": "456 Recipient Ave", "city": "Springfield", "state": "IL", "zip": "62701" } } }
{ "name": "postalform.create_form_order_draft", "arguments": { "request_id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "slug": "1099-nec", "fields": { "calendar_year": "2025", "payer_name": "Sender Example LLC", "payer_street_address": "123 Sender St", "payer_city_state_zip_phone": "Springfield, IL 62701, 217-555-0100", "payer_tin": "12-3456789", "recipient_tin": "123-45-6789", "recipient_name": "Contractor Example", "recipient_street_address": "456 Recipient Ave", "recipient_city_state_zip": "Springfield, IL 62701", "box_1_nonemployee_compensation": "1250.00" }, "sender_name": "Sender Example", "sender_address_type": "Address", "sender_address_id": "US|LP|Pz0_Qj4_bGJg|16074807|13_ENG", "sender_address_text": "123 Sender St, Springfield, IL 62701", "recipient_name": "Contractor Example", "recipient_address_type": "Manual", "recipient_address_manual": { "line1": "456 Recipient Ave", "city": "Springfield", "state": "IL", "zip": "62701" } } }
{ "name": "postalform.create_pdf_upload", "arguments": { "file_name": "letter.pdf", "content_type": "application/pdf", "content_length": 1234567 } }
{ "structuredContent": { "upload_url": "https://postalform.com/api/mcp/pdf-uploads/pfu_...", "upload_token": "pfu_...", "expires_at": "2026-01-17T12:00:00Z", "max_bytes": 104857600, "required_headers": { "Content-Type": "multipart/form-data" } } }
Upload the PDF with multipart/form-data using thefilefield (aliasespdfandpdfFileare also accepted), then passupload_tokentopostalform.create_order_draft.
Note:pdfaccepts a ChatGPT file object, anupload_token, or a base64 data URL (data:application/pdf;base64,...). If you pass a URL, it must be https and hosted on an allowlisted domain (default:.oaiusercontent.com). Request:
{ "name": "postalform.create_order_draft", "arguments": { "request_id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "pdf": { "upload_token": "pfu_..." }, "file_name": "letter.pdf", "sender_name": "Sender Example", "sender_address_id": "US|LP|Pz0_Qj4_bGJg|16074807|13_ENG", "sender_address_type": "Address", "sender_address_text": "123 Sender St, Springfield, IL 62701", "recipient_name": "Recipient Example", "recipient_address_id": "US|LP|Pz0_Qj4_bGJg|199825276|99_ENG", "recipient_address_type": "Address", "recipient_address_text": "456 Recipient Ave, Springfield, IL 62701", "double_sided": true, "color": false } }
{ "structuredContent": { "view": "order_draft", "order_id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "page_count": 2, "price_usd": 2.99, "checkout_url": "https://postalform.com/payment?orderId=8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "sender_name": "Sender Example", "sender_address_text": "123 Sender St, Springfield, IL 62701", "recipient_name": "Recipient Example", "recipient_address_text": "456 Recipient Ave, Springfield, IL 62701", "checkout_session": { "id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "payment_provider": { "provider": "stripe", "merchant_id": "profile_123", "supported_payment_methods": ["card", "apple_pay", "google_pay"] }, "status": "ready_for_payment", "currency": "usd", "line_items": [ { "id": "line_item_8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "item": { "id": "postalform_mail_pdf", "quantity": 1 }, "base_amount": 299, "discount": 0, "subtotal": 299, "tax": 0, "total": 299 } ], "totals": [ { "type": "items_base_amount", "display_text": "Items", "amount": 299 }, { "type": "subtotal", "display_text": "Subtotal", "amount": 299 }, { "type": "tax", "display_text": "Tax", "amount": 0 }, { "type": "total", "display_text": "Total", "amount": 299 } ], "links": [ { "type": "terms_of_use", "value": "https://postalform.com/terms" }, { "type": "privacy_policy", "value": "https://postalform.com/privacy" } ], "payment_mode": "test" } } }
First call for an MPP/Link payment challenge:
{ "name": "postalform.create_machine_order", "arguments": { "payment_protocol": "mpp", "request_id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "buyer_name": "Agent Owner", "buyer_email": "owner@example.com", "letter": { "title": "Payment demand letter", "body": "Hello,\\n\\nThis is the letter body.\\n\\nSincerely,\\n" }, "sender_name": "Sender Example", "sender_address_type": "Manual", "sender_address_manual": { "line1": "123 Sender St", "city": "Springfield", "state": "IL", "zip": "62701" }, "recipient_name": "Recipient Example", "recipient_address_type": "Manual", "recipient_address_manual": { "line1": "456 Recipient Ave", "city": "Springfield", "state": "IL", "zip": "62701" } } }
{ "structuredContent": { "view": "machine_order", "protocol": "mpp", "order_id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "status": "payment_required", "payment": { "www_authenticate": ["Payment ..."], "retry_header": "Authorization", "retry_header_value": "Payment ..." } } }
After Link CLI or Link MCP returns the paid MPP credential, retry the same arguments with:
{ "payment_authorization": "Payment ..." }
For x402, setpayment_protocoltox402; the first response containspayment.payment_required_header, and the retry usespayment_signature.
{ "name": "complete_checkout", "arguments": { "checkout_session_id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "buyer": { "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com" }, "payment_data": { "token": "spt_test_123", "provider": "stripe" } } }
{ "structuredContent": { "id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "buyer": { "first_name": "Jane", "last_name": "Doe", "email": "jane@example.com" }, "status": "completed", "currency": "usd", "line_items": [ { "id": "line_item_8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "item": { "id": "postalform_mail_pdf", "quantity": 1 }, "base_amount": 299, "discount": 0, "subtotal": 299, "tax": 0, "total": 299 } ], "fulfillment_options": [ { "type": "shipping", "id": "postalform_standard", "title": "First Class mail", "subtitle": "Mailed via postal carrier", "carrier": "Postal carrier", "carrier_info": "PostalForm print-and-mail provider", "earliest_delivery_time": "2026-07-01T00:00:00.000Z", "latest_delivery_time": "2026-07-06T00:00:00.000Z", "subtotal": 0, "tax": 0, "total": 0 } ], "fulfillment_option_id": "postalform_standard", "totals": [ { "type": "items_base_amount", "display_text": "Items", "amount": 299 }, { "type": "subtotal", "display_text": "Subtotal", "amount": 299 }, { "type": "tax", "display_text": "Tax", "amount": 0 }, { "type": "total", "display_text": "Total", "amount": 299 } ], "order": { "id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "checkout_session_id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "permalink_url": "https://postalform.com/order/complete?order_id=8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b" }, "messages": [], "links": [ { "type": "terms_of_use", "value": "https://postalform.com/terms" }, { "type": "privacy_policy", "value": "https://postalform.com/privacy" } ] } }
{ "structuredContent": { "view": "order_status", "found": true, "order_id": "8c1a1b58-2c8f-4f4f-9c46-2c1ac32d7a1b", "is_paid": true, "current_step": "letter_created" } }
{ "isError": true, "content": [ { "type": "text", "text": "recipient_address_manual is required when recipient_address_type is Manual." } ] }
- Idempotency: userequest_idon draft creation tools (postalform.create_order_draft,postalform.create_letter_order_draft,postalform.create_form_order_draft) and onpostalform.create_machine_order. Reuse the same value and same order fields on retries. The server will return the existing draft/order.
- Errors: tool calls that fail validation returnisError=truewith a human-readable message. For Instant Checkout,complete_checkoutcan also return ACP messages with error codes likepayment_declinedorrequires_3ds.
- Instant Checkout fallback: ifwindow.openai.requestCheckoutis unavailable orcheckout_session.payment_providerlacksmerchant_id, usecheckout_urlinstead.
- Order status steps:payment_received,receiver_address_verified,sender_address_verified,pdf_normalized,letter_created,email_sent,canceled,refunded,abandoned.
- All orders are printed from PDFs. Forpostalform.create_order_draftyou supply the PDF. Forpostalform.create_letter_order_draftandpostalform.create_form_order_draftPostalForm generates the PDF server-side. PDFs are sanitized before printing.
- Inlineform.attachmentsare base64 JSON and may total at most 12 MB after decoding. Follow each attachment'sallowed_types,max_files, and machine-cappedmax_size_mbvalues from the workflow schema.
- For a workflow withrecipient.mode="user", the top-level recipient name/address controls the envelope. Keep it aligned with recipient address-role fields inform.fields; those fields do not override the top-level machine-order address.
- Max 199 pages and 100 MB per file.
- download_urlmust be HTTPS and hosted on an allowlisted domain (ChatGPT attachments useoaiusercontent.comby default). The URL must be publicly reachable without auth headers. If you cannot provide an allowlisted URL, usepostalform.create_pdf_uploadto get anupload_token, or pass adata:application/pdf;base64,...URL instead.
- Address countries default toUSwhen omitted. Use Loqate address ids returned bypostalform.search_addresses(the id prefix carries the country), or use manual address input with_address_type="Manual"and_address_manual.countryCode. Machine orders enforce the same country list as the checkout address picker:US,CA,AT,BE,CH,DE,ES,FR,GB,IN,LU, andNL; unsupported or invalid codes are rejected. Bulk CSVs accept the same list throughcountry,country_code, orcountrycode.
- Address suggestions can includetype="Container"(buildings/complexes). Callpostalform.search_addressesagain withcontainer=<id>and a refined query (suite, unit, PO Box) to gettype="Address"results. Onlytype="Address"(not Container) is valid for Loqate-based order drafts.
MCP safety, permissions, and rate limits
Treat PostalForm as a real-world action tool because it can create mail drafts and, in machine-payment flows, place paid mail orders after an owner-approved payment challenge. In chat clients, configure the server withrequire_approval: "always"and require human review before sending user documents, addresses, or payment credentials.
Draft-creating tools and direct machine-order tools are also limited by unpaid-order throttling. The default unpaid-order creation limit is 10 attempts per hour per client IP. On rate limits, MCP tools return an error response and HTTP wrapper calls may return429.
Security scanners should treat hosted checkout as the default safe path: the tool can create a draft, but the customer still reviews the PDF, addresses, price, and mailing options before payment. Direct machine payment should stay behind explicit owner approval, spending limits, idempotentrequest_idvalues, and a preview review step whenpreview_urlis present.
- OpenAI remote MCP and connectors
- Model Context Protocol documentation
- Google Gemini MCP tools
- Stripe Machine Payments Protocol
- x402 payment protocol
- Is PostalForm a mail API?Yes. PostalForm exposes machine-order REST endpoints, an OpenAPI catalog, and a remote MCP server for creating physical-mail drafts, quotes, machine-payment orders, and fulfillment-status lookups.
- Can an MCP server send real postal mail?Yes, but PostalForm separates draft creation from paid mailing. Draft tools create an unpaid hosted-checkout draft; direct machine-order tools should be used only by authorized runtimes with spending controls and approval.
- What is the safest default for ChatGPT, Claude, Gemini, Cursor, or Codex?Use the remote MCP endpoint at[https://postalform.com/mcp, configure approval for mail side effects, create a hosted-checkout draft, and let the user review the PDF, addresses, price, and options before payment.
- Can an agent pay for mail with x402 or MPP?Yes. PostalForm supports direct machine-payment flows for authorized autonomous runtimes. The unpaid call returns a payment challenge, and the paid retry must include the x402 payment signature or MPP authorization.
- Do I need a PostalForm API key?Not for the current public MCP endpoint or machine-payment flow. Some high-volume, abuse-sensitive, or allowlisted deployments may require coordination withsupport@postalform.com.
- Can I upload PDFs through the API or MCP?Yes. Use the PDF upload tool to create a short-lived upload token, pass an allowlisted HTTPS download URL, use a ChatGPT attachment URL, or provide a data URL where supported.
- How do I keep mail side effects safe?Treat physical mail as a real-world action. Use hosted checkout by default, require human approval, set spend limits, reuse idempotency request IDs, and review preview URLs before payment when present.
Generate documents, process PDFs, and manage e-signature workflows using the PDFGate API.
…
Sign in to leave a review
Use Google, GitHub, or an email account so ratings stay tied to real people.
No reviews posted yet.





