Callbacks
Receive ticket events.
Configure signed webhooks or optional XRPC receivers, validate payloads, and redrive events safely.
Read as Markdown · Agent build guide
Webhooks
ATM delivers ticket events to private app receiver settings. Verify signatures, environment and payload before side effects; use durable recoverable deduplication. Event names use the exact punctuation shown here.
ticket.hold.created
ticket.hold.expired
tickets.issued
ticket.released
ticket.refunded
ticket.voided
ticket.partial-refund-review
ticket.failed-refund-review
ticket.event-canceled
ticket.checked-in
ticket.form-submitted
ticket.waitlist.joined
ticket.waitlist.offered
ticket.collaboration.invited
ticket.collaboration.accepted
ticket.collaboration.revoked
Receiver options
HTTP webhooks use Atm-Signature: t=<unix>,v1=<hex> and Atm-Delivery-Id. Verify the exact raw body; the signed input is timestamp.deliveryId.rawBody. Optional XRPC callbacks use ATM service-auth to the app's configured receiver, with the same current envelope and delivery headers.
POST https://app.example/xrpc/money.atmosphere.event.receive
Authorization: Bearer <ATM service-auth JWT for this receiver>
Atm-Delivery-Id: evt_example
Atm-Event: tickets.issued
Atm-API-Version: 2026-07
Atm-Environment: test
Streams are not a replacement for durable fulfillment callbacks. Persist delivery processing atomically with effects and recover interrupted deliveries before acknowledging success.
Webhook test console
Build a current-shaped callback command shell. Replace placeholder auth/signatures; sign the exact raw body and delivery id. Real delivery status and redrive live in ATM.
curl -X POST "https://your-app.example/webhooks/atm" \
-H "ATM-Signature: t=...,v1=..." \
-H "Atm-Delivery-Id: evt_demo" \
-H "Content-Type: application/json" \
--data '{"type":"tickets.issued","environment":"test","id":"evt_demo","createdAt":"2026-10-12T12:00:00.000Z","apiVersion":"2026-07","data":{"claimId":"claim_demo","hold":{"id":"thold_demo"},"tickets":[{"id":"tix_demo"}]}}'
Payload schemas
The current ATM envelope uses id, type, ISO createdAt, apiVersion, environment and data. Delivery identity is carried in Atm-Delivery-Id; do not invent required root deliveryId or appDid fields. Payload $type names live under money.atmosphere.event.defs.
| ticket.hold.created / expired | data.hold object, including its durable id. |
|---|---|
| tickets.issued | data.hold, nonempty data.tickets, and paymentId or claimId. Derive counts from the tickets array; issuedCount is not the current required contract. |
| ticket.checked-in | data.ticket plus data.checkIn.id/checkedInAt. |
| ticket.refunded / voided | paymentId, nonempty tickets, optional reason. |
| ticket.released | buyerDid, eventId, nonempty tickets; a free release has no payment row. |
| ticket.form-submitted | Ticket, type id, timestamp and answered field keys only. Full answers require authorized listTicketFormResponses. |
| ticket.waitlist.* | data.waitlist, with redacted ids/quantity and offer hold/expiry when offered. No contact email is delivered here. |
{
"id": "evt_example",
"type": "tickets.issued",
"createdAt": "2026-10-12T12:00:00.000Z",
"apiVersion": "2026-07",
"environment": "test",
"data": {
"$type": "money.atmosphere.event.defs#ticketsIssued",
"claimId": "claim_example",
"hold": { "id": "thold_example", "eventId": "tevt_example" },
"tickets": [{ "id": "tix_example", "eventId": "tevt_example", "ticketTypeId": "ttyp_free", "status": "active" }]
}
}
Event catalog
Subscribe to exact event names in ATM's app configuration. Issuance uses nested hold/ticket payloads; free release, cancellation, partial-refund review and failed-refund review are distinct lifecycle signals. A partial refund is not permission to choose arbitrary ticket ids to void.
Form events contain answered field keys, not answers. Waitlist notifications contain offer state, not buyer contact. Co-organizer collaboration is operational delegation with manual reconciliation intent, not automatic payment splitting.
The published beta.5 typed SDK does not yet enumerate every newer lifecycle event. Verify the signed generic envelope and validate its current schema for newer events until the coordinated SDK release.