POSTs for the whole subscription lifecycle to your server. The mechanics are in the webhooks chapter; this is the reference for the payloads you’ll receive.
The delivery envelope
Every delivery is aPOST with this body:
| Header | Value |
|---|---|
Duro-Signature | t=<unix>,v1=<hex hmac-sha256> |
Duro-Event-Id | the event id (dedupe on this) |
Duro-Event-Type | the event type |
The catalog
Event names are stable and canonical. Subscribe to exactly the ones you list when creating the endpoint (an empty list means all).Subscription lifecycle
Subscription lifecycle
| Event | When |
|---|---|
subscription_created | A subscription is created (incl. via checkout). |
subscription_activated | Trial converted, or first charge succeeded. |
subscription_updated | A mutable field changed (e.g. cancel-at-period-end set). |
subscription_plan_changed | Plan changed (immediate or scheduled). |
subscription_paused / subscription_resumed | Paused or resumed. |
subscription_past_due | A renewal failed; dunning has begun. |
subscription_recovered | Dunning won; the subscription is active again. |
subscription_unpaid | Dunning exhausted; written off. |
subscription_expired | Reached maxCycles. |
subscription_cancelled | Cancelled (immediately or at period end). |
Payments
Payments
| Event | When |
|---|---|
subscription_payment_success | A charge succeeded (renewal or checkout). |
subscription_payment_failed | A charge failed. |
subscription_payment_recovered | A previously-failed charge was recovered. |
subscription_payment_refunded | An invoice was refunded. |
subscription_payment_action_required | The customer must update their card. |
invoice_created | A renewal invoice was generated. |
Verifying a signature
Recompute the HMAC and compare in constant time. The signed payload is${t}.${rawBody} — use the raw request body, not a re-serialised object.
Retries & replay
A non-2xx response is retried on an exponential backoff (1m, 5m, 30m, 2h, 6h, 24h, six attempts). Make your handler idempotent — dedupe on Duro-Event-Id — because a slow 200 can still be retried. You can also replay any delivery from the dashboard’s delivery inspector.