Webhooks & reconciliation
Subscribe to subscription events to react to lifecycle changes and reconcile them against your own records. See Webhooks for endpoint setup, the signed-envelope format, signature verification, and retries; this page covers the subscription topics and how to reconcile them.
Topics
| Topic | Fires when |
|---|---|
subscription.assigned | Fired when a subscription is assigned to a customer (may be future-dated / upcoming). |
subscription.started | Fired when a subscription becomes active — grant entitlement/access on this event, not on assigned. |
subscription.updated | Fired when a config property changes without a structural transition (e.g. name, payment method, billing direction). |
subscription.transitioned | Fired on a structural change: plan replace, product edit, billing cadence change, phase change, or realign. |
subscription.paused | Fired when a subscription is paused. |
subscription.resumed | Fired when a subscription resumes from a pause. |
subscription.trial_ended | Fired when a subscription trial ends. The payload outcome says whether billing begins (ACTIVE) or the subscription was held for a missing payment card (PAUSED). |
subscription.cancellation_scheduled | Fired when a future cancellation is scheduled for a subscription (still active until then). |
subscription.cancellation_cleared | Fired when a previously scheduled cancellation is cleared. |
subscription.churned | Fired when a subscription is cancelled/finalized — revoke entitlement on this event. |
subscription.billed | Fired once per subscription that billed onto an invoice — one per child on a parent-paid consolidated invoice, one per member on a billing-group invoice. amount is always the whole document total; deduplicate on invoiceId, attribute on billingGroupId, never sum amount across events. |
subscription.payment_succeeded | Fired when a card charge for the subscription clears — the success pair of the charge_failed error signal. On a billing-group card charge one event fires per member, each carrying the full charged amount and the shared billingGroupId. |
subscription.error | Fired when a delivery/processing problem occurs for a subscription (e.g. undeliverable recipient). |
Entitlement synchronization
Access-boundary payloads include entitlementIds. Grant or replace access when
the subscription starts, transitions, resumes, or ends its trial. An assigned
event is advance notice and can describe a future start. Revoke access on an
effective pause or finalized cancellation. Both carry an empty array.
Do not infer access from billing or payment topics. Reconcile a missed event by reading the subscription detail endpoint. See Product Entitlements for the identifier and ownership contract.
subscription.error
The subscription.error topic reports a billing problem rather than a lifecycle
change.
The errorType field discriminates which problem occurred — it is one of:
errorType | Meaning |
|---|---|
recipient_undeliverable | A document recipient for the subscription is undeliverable (e.g. the email hard-bounced); the document was not delivered. |
charge_failed | A card charge (first or recurring) for the subscription failed. Automatic retries continue across the grace window, and this fires on each decline. The raw provider decline is not exposed on the payload. |
dunning_exhausted | Automatic card-charge retries for the subscription are exhausted after the grace window; no further automatic attempts will be made and the outstanding invoice becomes collectible. Fires once per subscription, distinct from the per-decline charge_failed — a billing group emits one per member, each naming that member, so "once per subscription" holds on both rails. |
Reconcile on the stable id
Every subscription.* event carries the stable id as data.subscriptionId, plus
data.partnerReferenceId and a diagnostics-only data.versionId. Reconcile on
subscriptionId or partnerReferenceId, never versionId — the version id
changes on every structural change (see
Data model).
partnerReferenceId is the clientReferenceId you pass when binding an
embedded checkout — your join key
for matching a subscription to your own order.
Recover a lost event
If a delivery is lost, recover the join over the API by your own reference:
Code
One invoice, several events
An invoice can carry more than one subscription: a parent that pays for its
children on one consolidated invoice, or a billing group whose members share
one document. Such an invoice produces one subscription.billed per
subscription on it. Every one of those events carries the same invoiceId and
invoiceNumber, and every one carries the whole document total as amount,
never that subscription's share. Deduplicate on invoiceId, and never sum
amount across events for the same invoice.
billingGroupId on the billed and payment-succeeded events, and on the
billing document events, names the set the document belongs to. It is null
on a subscription's own document. When the group pays by card, each member
receives the payment-succeeded event when the group's charge clears, and the
exhausted-retries error if it never does. Gate a member's access on those two:
the per-decline charge error is never raised for a member, and a member never
enters awaiting_payment.