Skip to main content
Subscription webhooks use a dedicated envelope. The top-level event is always subscription; the concrete event name is in data.event_type.

Example delivery payload

Failure events include the same subscription fields plus retry context such as attempt_number and failure_reason.

Events emitted today

  • subscription.created
  • subscription.started
  • subscription.renewed
  • subscription.updated
  • subscription.canceled
  • subscription.payment_failed
  • subscription.past_due
  • subscription.trial_will_end
  • subscription.chargeback_received

Pix Automático sequence

Pix Automático subscriptions use the same envelope and event names. What changes is when each event arrives:
  • Without a trial: no event at creation. subscription.started, with previous_status: "incomplete", arrives once the payer has authorized and the first debit is paid.
  • With a trial: subscription.created arrives when the payer approves the authorization (status trialing, latest_transaction: null). subscription.trial_will_end arrives 3 days before trial_end if the subscription is already trialing by then, and subscription.started with the first debit after it.
  • Rejected authorization, or, depending on the account configuration, an expired one: subscription.canceled, with failure_reason.
  • Later cycles: subscription.renewed for each paid debit. After a failed debit, subscription.payment_failed, plus subscription.past_due when the subscription moves to past_due.
  • Cancellation: subscription.canceled, never subscription.updated.
In these events latest_transaction.method is "pix". Pix Automático charges do not send transaction.* webhooks, and a failed debit does not create a transaction, so on failure events latest_transaction is the most recent transaction of the subscription. The full table is in Pix Automático Subscriptions.

Plan changes

Plan changes apply to card subscriptions only. A plan change does not introduce a new event type. It arrives as subscription.updated, and update_fields tells you what moved: ["product_id", "amount"] when the new plan is now being billed, ["pending_change"] when a change was scheduled or a scheduled one was cancelled. When a plan actually moves — immediately, or when it is scheduled — the payload also carries a plan_change block:
For a scheduled change, effective_at is the end of the current period; for an immediate one, it is the moment it was applied. Two cases deliberately arrive without plan_change, and its absence is how you tell them apart from the cases above:
  • A scheduled change was cancelled. You receive subscription.updated with update_fields: ["pending_change"] and no plan_change block.
  • A scheduled change took effect at renewal. No subscription.updated is sent for it. You receive the usual subscription.renewed, already carrying the new amount, and pendingChange is null on the next read.

Handling guidance

  • Deduplicate by the top-level event id.
  • Use data.event_type to route each event to the correct handler.
  • Use data.status for the current subscription state.
  • Use latest_transaction for the billing transaction linked to the event. On Pix Automático failure events, it is the most recent transaction of the subscription.
  • Use the UUID in data.id as the subscription identifier.
  • Reconcile with GET /v2/subscriptions/{id} if delivery or processing is interrupted.