billing.* events
The creator's own Subscriby subscription tier: trial conversion, invoices, payment failures, grace periods, lockdowns.
The creator's own Subscriby subscription tier: trial conversion, invoices, payment failures, grace periods, lockdowns. These events describe the creator's billing relationship with Subscriby itself, not their subscribers' billing. Useful for building ops dashboards that watch for accounts heading into lockdown.
Background
Example envelope
{
"id": "evt_01HX...",
"type": "billing.account_locked",
"created_at": "2026-05-18T10:05:00Z",
"api_version": "2026-05-01",
"project_id": null,
"data": {
"creator_id": "2a91c4e7-6f38-4b52-8e0d-9c1a7b3f5d80",
"past_due_since": "2026-04-18T00:00:00Z",
"locked_at": "2026-05-18T00:00:00Z"
}
}project_id is always null for billing.* events; these are account-level.
When you'd subscribe
The typical consumer is an internal ops dashboard or Slack room, not a subscriber-facing system. Subscriby also emails the creator via the existing notification channels for every one of these events.
Required ability
Tokens subscribing to billing.* events must carry billing:read at mint time. Writes (upgrade, downgrade, cancel) additionally need billing:manage.
Events
billing.invoice_createdA new invoice is generated for the creator's Subscriby tier.billing.invoice_paidAn invoice is paid in full.billing.invoice_overdueA creator invoice is marked overdue.billing.payment_failedA recurring charge against the creator's payment method fails.billing.trial_endingThe creator's platform trial is about to convert and take its first payment.billing.grace_period_warningThe creator is approaching automatic lockdown for an unpaid invoice.billing.account_lockedThe account hits its past-due lockdown.billing.tier_upgradedThe creator upgrades to a higher Subscriby tier.billing.tier_downgradedThe creator downgrades to a lower Subscriby tier.billing.tier_cancelledThe creator cancels their Subscriby subscription.billing.invoice_created
WEBHOOKA new invoice is generated for the creator's Subscriby tier.
When this fires
A new invoice is generated for the creator's Subscriby tier subscription. These events describe the creator's relationship with Subscriby itself, not their subscribers.
Caveats
- This event is creator-side only. Subscriber invoices, if any, are not represented in
billing.*. - Pairs with
billing.invoice_paidon success andbilling.payment_failedwhen the first attempt fails.
Related events
billing.invoice_paid: successful collection.billing.payment_failed: failed collection attempt.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
billing.invoice_paid
WEBHOOKAn invoice is paid in full.
When this fires
The creator's tier invoice is paid in full and the account is marked current.
Caveats
- Expect two deliveries per payment. Subscriby maps both Stripe
invoice.paidandinvoice.payment_succeededonto this event. De-duplicate ondata.invoice_id. - Recovery is not driven by this event.
past_due_since,locked_atand the warning stamps are cleared when Stripe reports the subscription back atactive/trialingoncustomer.subscription.updated, which emits nobilling.*event of its own, so a consumer tracking lock state should treat this event as a hint, not the unlock signal. - A creator's lockdown never suspends their subscribers' billing (only new signups are blocked), so there is nothing to resume here.
Related events
billing.invoice_created: predecessor.billing.payment_failed: alternative outcome.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
billing.invoice_overdue
WEBHOOKA creator invoice is marked overdue.
When this fires
The creator's invoice is marked uncollectible by the payment provider. Coverage is partial: providers do not always send this signal for every overdue scenario.
Deferred coverage. Wired only to Stripe's
invoice.marked_uncollectiblesignal. Stripe does not send that for every overdue scenario, so gaps are possible. Pair this event withbilling.payment_failedandbilling.grace_period_warningto cover overdue states reliably.
Caveats
- Deferred in practice: coverage depends on Stripe sending
invoice.marked_uncollectible. For full coverage of overdue states, listen forbilling.payment_failedandbilling.grace_period_warning. - The billing overdue policy drives lockdowns on its own daily cadence; see
billing.account_locked.
Related events
billing.payment_failed: typical earlier signal.billing.grace_period_warning,billing.account_locked: downstream signals.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
billing.payment_failed
WEBHOOKA recurring charge against the creator's payment method fails.
When this fires
A scheduled charge against the creator's payment method fails. The platform will continue to retry inside the grace window.
Caveats
- Multiple
billing.payment_failedevents can fire for the sameinvoice_idas Stripe retries. - Repeated failures escalate through the grace window; see
billing.grace_period_warningandbilling.account_lockedfor that progression.
Related events
billing.invoice_paid: successful resolution.billing.account_locked: terminal state if recovery doesn't happen.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
billing.trial_ending
WEBHOOKThe creator's platform trial is about to convert and take its first payment.
When this fires
The creator's own Subscriby trial crosses a reminder milestone on its way to converting. The trial collects a card at checkout and converts by itself, so this is the only advance notice a consumer gets before the first charge appears.
Milestones are configured per deployment and fire largest-first. The default ladder is 72 hours then 24 hours before trial_ends_at, so a standard 7-day trial produces exactly two events. A milestone wider than the trial itself is skipped rather than fired at signup, so a trial shorter than 72 hours emits only the 24-hour event. Fires once per milestone, not once per trial; read hours_remaining to tell the two apart.
Subscriby emails the creator alongside every emission, and mirrors it to their connected account when one is linked.
Reading amount correctly
When amount_estimated is false, the figure comes from the upcoming Stripe invoice and already includes tax, any discount, and the transaction fees the creator's own sales metered during the trial. It is what will actually be taken.
When amount_estimated is true, Stripe could not be reached and the figure is the plan's current price including any promotion in force. Treat it as indicative: do not reconcile against it, and do not surface it as a confirmed charge.
A creator carrying a credit grant or account balance will legitimately see "0.00"; the trial still converts, the invoice is simply covered.
Caveats
- Not once per trial. The default ladder emits twice. De-duplicate on
subscription_id+hours_remainingif your consumer must act only once. - A trial the creator cancels before it converts stops emitting: no further milestones fire and no charge is raised.
- The milestone ladder is deployment configuration, so do not hard-code
72and24. Readhours_remaining. hours_remainingis the milestone that fired, not the exact time left. The sweep runs hourly, so the true remaining time is somewhere within an hour below the value.
Related events
billing.invoice_created: the invoice this warning was about, once the trial actually converts.billing.payment_failed: fires instead if the card on file is declined at conversion.subscription.trial_converting: the subscriber-tier equivalent, for a creator's own members.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
billing.grace_period_warning
WEBHOOKThe creator is approaching automatic lockdown for an unpaid invoice.
When this fires
The creator's account reaches the warning milestone on its overdue clock. That milestone depends on the plan's base price: day 3 for a creator on a zero-base-price (Free) plan, whose lockdown lands on day 7, and day 23 for a paid plan, whose lockdown lands on day 30. Fires once per past-due cycle.
Read days_until_lockdown from the payload rather than assuming a fixed offset; it carries the actual remaining days for that creator's tier.
Caveats
- Each past-due cycle produces at most one
billing.grace_period_warning. If the account recovers and re-enters past_due later, a new cycle and a new warning may issue. - After lockdown the clock keeps running: a deletion warning at 53 days locked and account deletion at 60 days locked on paid/trial thresholds (3 and 7 days on Free). Neither stage emits a
billing.*webhook; they surface as notifications only.
Related events
billing.payment_failed: the chain of failed collections leading here.billing.account_locked: fires when the lockdown day arrives: 7 days after this event on a paid tier, 4 on Free or an unconverted trial.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
billing.account_locked
WEBHOOKThe account hits its past-due lockdown.
When this fires
The creator's account reaches its tier's past-due lockdown: day 30 on a paid tier, day 7 on Free or an unconverted trial. New signups on the project's portal pages are blocked and the dashboard surfaces a lockdown banner.
Caveats
- Lockdown is reversible: a successful payment fires
billing.invoice_paidand the lockdown is cleared automatically. There is no dedicated "account_unlocked" event. - Existing subscribers retain access to project resources during lockdown; only new signups are blocked.
Related events
billing.grace_period_warning: the warning that precedes it, 7 days earlier on a paid tier and 4 on Free or an unconverted trial.billing.invoice_paid: automatic unlock signal.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
billing.tier_upgraded
WEBHOOKThe creator upgrades to a higher Subscriby tier.
When this fires
The creator switches their Subscriby subscription to a higher-priced tier. Pro-ration is applied through the payment provider, except when the creator is still inside their platform trial, where the switch is not prorated because nothing has been paid yet.
Caveats
- Tier changes can unlock features (e.g. Teams on Growth+); event consumers should refresh tier caches on receipt.
- Pro-ration charges fire
billing.invoice_createdseparately for the proration line (not on an upgrade taken during the platform trial).
Related events
billing.tier_downgraded: opposite direction.billing.invoice_created: proration invoice.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
billing.tier_downgraded
WEBHOOKThe creator downgrades to a lower Subscriby tier.
When this fires
The creator switches their Subscriby subscription to a lower tier. The change lands at the end of the period they have already paid for, not at effective_at: the current phase runs to its existing end date and the lower tier begins after it.
Caveats
effective_atis stamped at emission time and is never in the future, even when the provider defers the billing change to the next renewal boundary. Do not use it to schedule feature revocation.- Tier-locked features (Teams, custom roles, etc.) may become read-only or hidden once the current paid period ends, never at
effective_at.
Related events
billing.tier_upgraded: opposite direction.billing.tier_cancelled: terminal downgrade path.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
billing.tier_cancelled
WEBHOOKThe creator cancels their Subscriby subscription.
When this fires
The creator cancels their Subscriby tier subscription. The account remains usable until the current period ends.
This event has two distinct payload shapes depending on which side initiated the cancellation. Branch on the presence of effective_at versus subscription_id.
Caveats
- Expect this event twice for a single cancellation. The dashboard shape fires when the creator cancels; the provider shape fires later, when the period actually ends and the provider deletes the subscription. De-duplicate on
data.creator_idif you only want to act once. - Cancellation does not refund the active period; there is a no-refunds policy on creator tier billing.
- The account does not auto-lock at
effective_atunless past_due conditions also apply; it gracefully drops to the Free tier feature set.
Related events
billing.tier_downgraded: alternative path that retains paid features.billing.invoice_paid: last paid invoice before cancellation.
Ability to subscribe
A token needs this to subscribe an endpoint to the event.
Header Parameters
t=<unix seconds>,v1=<hex>: the HMAC-SHA256 of "<t>.<raw body>" under the endpoint's secret. Verify it before acting, and refuse a t more than 300 seconds from now. During a secret rotation a v0= signature under the previous secret may precede v1=.
The event's ULID, bare. The envelope's id is the same ULID prefixed evt_, so strip the prefix before comparing. Deduplicate on it: a retry carries the same id.
The event name, the same as the envelope's type.
Always application/json.
Always Subscriby-Webhooks/1.0.
Payload
JSONWhat Subscriby posts to your endpointapplication/json
The signed JSON envelope posted to your endpoint.
The envelope every event is delivered in.
Responses
2XXAny success status
Your endpoint acknowledged the delivery. Any 2xx status within 30 seconds marks it delivered; the response body is ignored.
defaultAny other status
Any other status, a connection failure, or no answer within 30 seconds counts as a failed attempt. The delivery is retried 8 times, after 10 seconds, 30 seconds, 2 minutes, 10 minutes, 1 hour, 6 hours, 1 day, 3 days; the last failure dead-letters it, and it can be retried from the dashboard or POST /v1/webhook-deliveries/{delivery}/retry. After 20 consecutive failures the endpoint is paused until it is resumed.
How is this guide?