Webhook events
Canonical ATM event shapes for app fulfillment, subscriptions, ticketing, and operational redrive.
Compatible with the closed-beta ATM app APIs and versioned ATM event headers. Check atm-api-version on every webhook or XRPC receiver event.
Event envelope
Every app event carries delivery metadata, an environment, a type, and a typed data payload. HTTP webhooks are signed with the app environment secret. XRPC receiver callbacks are authenticated by service-auth in the opposite direction.
{
"id": "evt_...",
"deliveryId": "del_...",
"environment": "test",
"type": "payment.completed",
"appDid": "did:plc:app",
"createdAt": "2026-06-05T00:00:00.000Z",
"data": {}
}Event catalog
This catalog is generated from the same event definition list used by the app dashboard event selector. If an event appears here, apps can subscribe to it in their test or live environment when the matching module is enabled.
| Event | Module | Purpose | Example |
|---|---|---|---|
| app.webhook.test | core | Test eventA manual ping from the app dashboard to verify signatures and delivery. | {"message":"ATM webhook test event"} |
| payment.completed | payments | Payment completedA one-time, product, commission, ticket, or subscription invoice payment settled. | {"payment":{"id":"pmt_...","status":"completed","amountCents":500,"currency":"usd"}} |
| payment.failed | payments | Payment failedA checkout or invoice payment failed before settlement. | {"payment":{"id":"pmt_...","status":"failed"},"reason":"payment_failed"} |
| payment.refunded | payments | Payment refundedA payment was fully or partially refunded. | {"payment":{"id":"pmt_...","status":"refunded"},"amount":500,"reason":"refunded"} |
| payment.disputed | payments | Payment disputedThe payer opened a dispute or chargeback for an app-originated payment. | {"payment":{"id":"pmt_...","status":"disputed"},"status":"needs_response"} |
| subscription.invoice_paid | subscriptions | Subscription invoice paidA recurring subscription invoice settled. | {"payment":{"id":"pmt_..."},"invoice":{"id":"in_...","firstInvoice":false},"invoiceId":"in_..."} |
| subscription.updated | subscriptions | Subscription updatedA subscription amount or status changed through ATM. | {"subscription":{"id":"pmt_...","status":"active"},"payment":{"id":"pmt_new..."},"priorAmountCents":500,"amountCents":700,"currency":"usd","updatedAt":"2026-05-27T00:00:00.000Z"} |
| subscription.cancelled | subscriptions | Subscription cancelledA subscription was cancelled through ATM or processor state. | {"subscription":{"id":"pmt_...","status":"cancelled"},"payment":{"id":"pmt_..."},"cancelledAt":"2026-05-27T00:00:00.000Z"} |
| payer.record.requested | payments | Payer record requestedATM is asking a delegated app to write the canonical payer record. | {"paymentId":"pmt_...","payerDid":"did:plc:...","recipientDid":"did:plc:...","collection":"network.attested.payment.oneTime","canonicalRecord":{},"expectedCid":"bafy...","expiresAt":"2026-05-27T00:00:00.000Z"} |
| creator.proof.requested | payments | Creator proof requestedATM is asking a delegated app to write the canonical creator proof. | {"paymentId":"pmt_...","creatorDid":"did:plc:...","attestationCid":"bafy...","proofRecord":{},"expiresAt":"2026-05-27T00:00:00.000Z"} |
| attestation.updated | payments | Attestation updatedOne of the payer, broker, or creator proof slots changed. | {"paymentId":"pmt_...","attestations":{"broker":{"status":"saved"}}} |
| product.updated | products | Product updatedShared ATM catalog fields changed for a product fulfilled by this app. | {"product":{"uri":"at://did:plc:.../money.atmosphere.product/..."}} |
| product.archived | products | Product archivedA product was removed from sale while keeping payment history intact. | {"product":{"active":false,"archivedAt":"2026-05-27T00:00:00.000Z"}} |
| product.deleted | products | Product deletedA hard delete/tombstone path ran for a public product record. | {"product":{"uri":"at://did:plc:.../money.atmosphere.product/..."}} |
| ticket.hold.created | tickets | Ticket hold createdA buyer reserved ticket capacity before checkout. | {"hold":{"id":"th_...","eventId":"evt_..."}} |
| ticket.hold.expired | tickets | Ticket hold expiredA ticket hold expired or was released before payment. | {"hold":{"id":"th_...","status":"expired","reason":"expired"}} |
| tickets.issued | tickets | Tickets issuedA paid checkout issued one or more tickets. | {"paymentId":"pmt_...","tickets":[{"id":"tkt_..."}]} |
| ticket.voided | tickets | Ticket voidedA ticket was voided after a dispute, reversal, or admin action. | {"paymentId":"pmt_...","reason":"voided"} |
| ticket.refunded | tickets | Ticket refundedA refund changed the ticket state. | {"paymentId":"pmt_...","reason":"refunded"} |
| ticket.checked_in | tickets | Ticket checked inA ticket was verified and checked in. | {"ticket":{"id":"tkt_...","status":"active"},"checkIn":{"id":"tchk_...","checkedInAt":"2026-05-27T00:00:00.000Z"}} |
Payment events
payment.completed
A one-time payment or first subscription invoice has settled and can be fulfilled.
{
"paymentId": "pay_...",
"amount": 500,
"currency": "usd",
"paymentType": "shop",
"recipientDid": "did:plc:creator",
"payerDid": "did:plc:buyer",
"listing": { "uri": "at://...", "cid": "bafy..." }
}payment.refunded
A payment was refunded. Apps should reverse fulfillment when appropriate.
{
"paymentId": "pay_...",
"refundId": "re_...",
"amountRefunded": 500,
"currency": "usd"
}payment.disputed
A payment has a dispute or chargeback state that may require fulfillment review.
{
"paymentId": "pay_...",
"disputeId": "dp_...",
"status": "needs_response"
}Subscription events
subscription.updated
A subscription amount, status, or payment method state changed.
{
"subscriptionId": "sub_...",
"status": "active",
"amount": 1000,
"previousAmount": 500,
"currency": "usd"
}subscription.canceled
A subscription was canceled through ATM or the underlying billing rail.
{
"subscriptionId": "sub_...",
"status": "canceled",
"canceledAt": "2026-06-05T00:00:00.000Z"
}Catalog events
product.updated
Shared public catalog fields changed.
{
"productUri": "at://did:plc:creator/money.atmosphere.product/abc",
"productCid": "bafy...",
"changedFields": ["title", "price"]
}product.archived
A product was removed from sale but kept for historical receipts and payments.
{
"productUri": "at://did:plc:creator/money.atmosphere.product/abc",
"archivedAt": "2026-06-05T00:00:00.000Z"
}Ticket events
ticket.hold.created
A ticket hold reserved capacity before checkout.
{
"holdId": "hold_...",
"eventUri": "at://...",
"expiresAt": "2026-06-05T00:10:00.000Z"
}tickets.issued
Ticket issuance completed after ATM confirmed payment or a free claim.
{
"paymentId": "pay_...",
"eventUri": "at://...",
"issuedCount": 2
}ticket.checked_in
A ticket token was verified and checked in.
{
"ticketId": "ticket_...",
"eventUri": "at://...",
"checkedInAt": "2026-06-05T00:00:00.000Z"
}Verification
- Verify webhook signatures against the raw body.
- Deduplicate by delivery id before side effects.
- Use the environment field to separate test from live traffic.
- Redrive events from the app dashboard if delivery fails.