PostalForm · AsyncAPI Specification

Postalform Com Projects Webhooks

Version

View Spec View on GitHub Physical MailPrint & MailPostal MailCertified MailDocumentsAgentsAgentic CommerceMCPA2Ax402Machine PaymentsWebhookAgent-NativeUnited StatesAsyncAPIEvents

AsyncAPI Specification

Raw ↑
generated: '2026-09-19'
method: searched
source: openapi/postalform-com-projects-openapi.json
spec_type: Webhooks
asyncapi_published: false
docs:
- https://postalform.com/developer-mail-api
- https://projects.postalform.com/llm-context.txt
- https://postalform.com/developers/quickstart
summary: >-
  PostalForm publishes no AsyncAPI document (/.well-known/asyncapi.yaml and /asyncapi.yaml 404; none in the
  GitHub org), so none is recorded and nothing is fabricated. It DOES document a real webhook surface on the
  PostalForm Projects API: customer-configured HTTPS endpoints (createWebhookEndpoint) receive signed
  fulfillment events for letters and postcards, with a per-endpoint signing secret returned once and
  rotatable, automatic retries with next_retry_at, an event log (listWebhookEvents) and manual replay
  (replayWebhookEvent). The event names, payload schema and delivery-attempt record are all declared in the
  Projects OpenAPI components (CustomerWebhookEventType, CustomerWebhookPayload, WebhookEvent,
  WebhookDeliveryAttempt). The Machine Payments API and the MCP server have no outbound webhooks — agents poll
  the status endpoints; "settled_pending_webhook" there refers to PostalForm's own inbound Stripe webhook.
surface:
  api: PostalForm Projects Public API
  base_url: https://projects.postalform.com/api/v1
  auth_for_management: bearer pf_test_ / pf_live_ API key
  endpoint_requirements: 'url must match ^https://'
  signature_header: PostalForm-Signature
  signing_secret: 'signing_secret returned only on createWebhookEndpoint and rotateWebhookEndpointSecret (WebhookEndpointSecretResponse); endpoint-scoped'
  retries: 'Failed deliveries are retried; each attempt is recorded as WebhookDeliveryAttempt {attemptNumber, status succeeded|failed, httpStatus, responseBodySnippet, attemptedAt, nextRetryAt}'
  replay: 'POST /webhook-events/{event_id}/replay (replayWebhookEvent) queues a delivery again'
  test_mode: 'Webhooks fire in test mode with simulated timelines (developer-mail-api: pf_test_ keys "simulate uploads, quotes, orders, timelines, and webhooks")'
management_operations: [listWebhookEndpoints, createWebhookEndpoint, disableWebhookEndpoint, rotateWebhookEndpointSecret, listWebhookEvents, replayWebhookEvent]
events:
- {name: postalform.letter.accepted, description: 'Letter accepted for production or mailing after the order leaves PostalForm''s preparation queue.'}
- {name: postalform.letter.in_transit, description: 'Letter entered the mail stream. The payload may include or update mailpiece.tracking_number when tracking is available.'}
- {name: postalform.letter.delivered, description: 'Letter reported delivered by the carrier or delivery network.'}
- {name: postalform.letter.returned, description: 'Letter returned or otherwise marked undeliverable.'}
- {name: postalform.letter.failed, description: 'Letter could not be produced or mailed. Inspect the order timeline and retry with a corrected request when appropriate.'}
- {name: postalform.letter.canceled, description: 'Letter canceled before delivery completion.'}
- {name: postalform.postcard.accepted, description: 'Postcard twin of letter.accepted.'}
- {name: postalform.postcard.in_transit, description: 'Postcard twin.'}
- {name: postalform.postcard.delivered, description: 'Postcard twin.'}
- {name: postalform.postcard.returned, description: 'Postcard twin.'}
- {name: postalform.postcard.failed, description: 'Postcard twin.'}
- {name: postalform.postcard.canceled, description: 'Postcard twin.'}
payload:
  schema: CustomerWebhookPayload
  shape:
    id: 'string (example evt_123)'
    type: CustomerWebhookEventType
    data: {object: Letter}
    mailpiece: {status: 'string|null', tracking_number: 'string|null', tracking_status: 'string|null'}
  note: data.object is the full Letter (or postcard) resource including status, mode, price_cents, tracking fields, err_* return-receipt fields and caller metadata.
event_log_record:
  schema: WebhookEvent
  fields: [id, workspaceId, orderId, eventType, payload, createdAt, 'deliveries[]']
inconsistency_recorded:
  note: >-
    https://postalform.com/developers/quickstart lists a DIFFERENT event vocabulary — mail.order.created,
    mail.order.paid, mail.order.submitted, mail.order.provider_accepted, mail.order.provider_rejected,
    mail.order.mailed, mail.order.tracking_updated, mail.order.delivery_attempted, mail.order.delivered,
    mail.order.failed, mail.order.refunded — for a /v1/test API whose routes 404 live. The Projects OpenAPI
    (the served contract) is authoritative for the twelve postalform.letter.* / postalform.postcard.* names
    above; the quickstart names are recorded here only so a reader is not surprised by them.

Work with this as data

Every AsyncAPI spec here is available over the APIs.io API and to AI agents over MCP.

MCP server

One button, every client — Claude, Cursor, VS Code and the rest.

https://apis.io/mcp

Tools for asyncapi

4 MCP tools reach this
  • find_asyncapisBrowse and filter every AsyncAPI spec in the catalog.
  • apis_io_searchSTART HERE — APIs, providers and tags for one query, each with its total.
  • resolveTurn a domain, URL or GitHub org into the provider it belongs to.
  • find_cohortsEvery scored population of providers in the catalog.
All 92 tools →

Call it yourself

curl for this page
This AsyncAPI spec
curl "https://apis.io/api/v1/asyncapis/postalform-com-projects-webhooks"
All asyncapi
curl "https://apis.io/api/v1/asyncapis?limit=25"

Discovery needs no key. Ratings and market analysis are Pro.

Get an API key

Free tier, no form to fill in. Signing in shares your email address with us — we store it to create your key and to recognise you if you sign in with another provider. See our Privacy Policy and Terms.

A second provider on the same verified email joins the account you already have.