Webhooks and XRPC
Receive ATM wake-ups through the default AT-native XRPC receiver or signed HTTP webhook compatibility.
Compatible with the closed-beta ATM app APIs and versioned ATM event headers. Check atm-api-version on every webhook or XRPC receiver event.
Delivery choices
New AT Protocol-native registrations default to the canonical#AtmEventReceiver service andmoney.atmosphere.event.receiveEvent method. Conventional web apps can explicitly select signed HTTP webhooks by supplying a URL. ATM stores and redrives either wake-up transport; always reconcile canonical status/query state before fulfillment.
Explicit transport: "none"disables app-facing push. Its retainedlistEvents projection returns only successfully delivered test receiver history for diagnostics. It is not a complete log, fulfillment source, recovery feed, or current state, and it can never pass live readiness.
Live XRPC receiver and webhook deliveries are notifications only. Query canonical ATM status/current state before irreversible fulfillment.
Delivery is at-least-once but not indefinite: a failing delivery is retried up to 14 attempts with exponential backoff (capped at 24 hours between attempts), keeping it retryable for roughly three days — mirroring Stripe's webhook retry window. After the final attempt the delivery is marked failed and automatic retries stop; fix your receiver, then redrive it from the dashboard delivery log (the redrive keeps the original Atm-Delivery-Id, so idempotent receivers treat it as the same event). If an outage outlasts the window, reconcile from the query endpoints instead of waiting for a webhook that will no longer come.
Default XRPC receiver
AT Protocol-native apps receive events through money.atmosphere.event.receiveEvent. This keeps ATM integration on the same DID-discoverable service-auth surface as the rest of the app's XRPC contract.
Event envelope
Event payloads include delivery, environment, wire-format version, and event type metadata. The envelope id IS the delivery id — it matches the Atm-Delivery-Idheader — so use it for idempotency. Apps should verify the signature or service-auth envelope before processing the event.
{
"id": "whd_...",
"type": "payment.completed",
"createdAt": "2026-06-05T00:00:00.000Z",
"apiVersion": "2026-07",
"environment": "test",
"data": {
"$type": "money.atmosphere.event.defs#paymentCompleted",
"paymentId": "pay_...",
"amount": 500,
"currency": "usd",
"recipientDid": "did:plc:creator"
}
}Idempotency
Webhook delivery is at-least-once. Store the delivery id and ATM object id before performing side effects. Redriven events should be safe to receive multiple times.