Events
QuotaStack POSTs one of these events to your webhook URL when something happens. Every entry links to its payload shape, when it fires, and when it does not.
credit.*
-
credit.consumedFired when credits are consumed (debit ledger entries committed). -
credit.exhaustedFired once when a customer's effective balance crosses from > 0 to ≤ 0 (consumption, reservation create/commit, or expiry). Always enabled. Effective may be negative when reserved holds remain after balance drops; that still counts as exhausted. Re-arms when effective recovers above 0. A high→≤0 one-shot emits exhausted only (not also low_balance). -
credit.expiredFired when a credit block's remaining balance expires (the block reached its expires_at). data is the expiry ledger entry; its amount is the millicredits written off. See credit.expiring_soon for the proactive lead-time warning. -
credit.expiring_soonFired once per credit block when that block's remaining balance will expire within the tenant's credit_expiring_soon_hours lead window (default 0 = off; recommended 72). Distinct from credit.expired (fires when the block actually expires) and from post-expiry credit.exhausted / credit.low_balance. Debounced per (customer, block_id); emission is best-effort. -
credit.grantedFired when credits are granted to a customer (any source). -
credit.low_balanceFired once when a customer's effective balance (balance − reserved) crosses below the configured low_balance threshold while remaining > 0. Re-arms on grant / reservation release when effective recovers to or above threshold. Default tenant threshold is 0 (off). Exhausted cliff (high → ≤0) does not emit this event.
subscription.*
-
subscription.canceledFired when POST /v1/subscriptions/{id}/cancel cancels a subscription — immediately or at period end (inspect data.status and data.cancel_at_period_end). -
subscription.contract_endedFired when a postpaid contract_end is reached. -
subscription.contract_ending_soonFired N days before a postpaid contract_end (per subscription.contract_ending_soon_days). -
subscription.createdFired when a subscription is created via POST /v1/subscriptions (including trials). Not fired for imported subscriptions — those emit subscription.imported instead. -
subscription.downgradedFired when a downgrade is requested via POST /v1/subscriptions/{id}/downgrade. The variant change applies at the next renewal; data is the subscription with the pending change. -
subscription.expiredFired when an overdue subscription passes its grace period. -
subscription.importedSubscription imported via legacy cutover. -
subscription.pausedFired when POST /v1/subscriptions/{id}/pause pauses a subscription. -
subscription.renewal_dueFired N days before a prepaid subscription's period_end (default 3). -
subscription.renewal_overdueFired when a prepaid subscription's period_end passed without renewal. -
subscription.renewedFired when a subscription advances into a new billing period — prepaid renewal, postpaid auto-advance, scheduled downgrade, or the tenant-called POST /renew. Unlike the other subscription events, data is NOT a Subscription object: it is a unified renewal summary carrying the just-ended period's usage/overage rollup. -
subscription.resumedFired when POST /v1/subscriptions/{id}/resume resumes a paused subscription. -
subscription.upgradedFired when POST /v1/subscriptions/{id}/upgrade switches the plan variant (effective immediately). data is the post-upgrade subscription.
customer.*
-
customer.importedCustomer imported via legacy cutover.
test.*
-
test.pingManually triggered test event (POST /v1/webhooks/test). Signed and delivered like every real event. data.message says what it is; data.requested_at is when the test was requested.
21 of 21 events documented in full.