Version

subscription.* events

Every transition across the subscription statuses, plus upgrade / downgrade.

Every transition across the subscription statuses, plus upgrade / downgrade. The busiest event family. Subscribe to these to drive CRM timelines, revenue dashboards, churn-risk pipelines, and Slack alerts.

Background

Example payload

subscription.* payloads carry flat identifier fields, not nested subscription / plan / subscriber objects. Every event in the family includes subscription_id and subscriber_id. All of them except subscription.upgraded and subscription.downgraded also include plan_id; those two carry from_plan_id and to_plan_id instead. The remaining keys vary per event, so check the individual event.

{
  "id": "evt_01HX...",
  "type": "subscription.activated",
  "created_at": "2026-05-18T10:05:00Z",
  "api_version": "2026-05-01",
  "project_id": "7f3d1c92-8b45-4e6a-9d21-5c8e0a4b6f13",
  "data": {
    "subscription_id": "5b7e2d40-1a86-4c39-97f2-e83d0b16c5a4",
    "plan_id": "c4e82f16-93a7-4d5b-b81c-6e0f27a94d3b",
    "subscriber_id": "2a91c4e7-6f38-4b52-8e0d-9c1a7b3f5d80",
    "provider": "stripe"
  }
}

Plan pricing, subscriber identity, and period boundaries are not embedded. Resolve them with the subscription endpoint and the member endpoint.

Guarantees

  • Every acquisition emits exactly one of subscription.activated (paid) or subscription.created (access code, cardless trial), never both. Subscribe to both and de-duplicate on data.subscription_id to cover all acquisition paths.
  • subscription.activated fires at most once per subscription. Renewals emit subscription.renewed instead.
  • Out-of-order delivery is possible during retries. Use SB-Event-Id to de-dupe and created_at to sequence.

Required abilities

Tokens subscribing to subscription.* events must carry project-subscription:view.

Events

subscription.created

WEBHOOK

New subscription created via access-code redemption or cardless trial.

When this fires

Exactly two paths emit this event:

  • Access-code redemption: a subscriber redeems a code against a plan.
  • Cardless trial start: a subscriber begins a trial that took no payment method.

Both are zero-payment acquisitions. Every paid acquisition (every payment provider, both recurring subscriptions and one-time passes) emits subscription.activated instead, and never emits subscription.created.

This event does not fire for paid checkouts. A card, wallet, or crypto purchase emits subscription.activated instead. If you are building access control for a paying audience, subscribe to both.

The data keys differ by path. Absent keys are omitted entirely, not sent as null.

access_code carries the complete code. It is already consumed and cannot be redeemed again, but treat it as you would any other customer identifier and avoid logging it into systems you do not control.

Caveats

  • Do not treat this as the universal "a subscription exists" signal. For paid projects it never fires. The reliable pattern is to subscribe to both subscription.created and subscription.activated and de-duplicate on data.subscription_id.
  • The access-code path also emits access_code.redeemed and either member.joined or member.trial_joined for the same subscription.
  • The cardless-trial path also emits subscription.trial_started and member.trial_joined.
  • The POST /v1/webhook-endpoints/{endpoint}/test endpoint sends a synthetic subscription.created payload regardless of your project's payment configuration. A successful test does not prove this event will fire in production.

Related events

  • subscription.activated: the paid-checkout equivalent.
  • access_code.redeemed: fires alongside on the access-code path.
  • subscription.trial_started: fires alongside on the cardless-trial path.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.activated

WEBHOOK

A paid subscription is acquired. Fires once, at first activation.

When this fires

On the first successful payment for a subscription, across every payment provider: Stripe, PayPal, Paystack, Razorpay, Skrill, CeyPay, and CoinPayments. It covers both recurring subscriptions and one-time (non-recurring) passes.

It fires once per subscription, at acquisition. It is not a general "became active" signal:

TransitionEvent actually emitted
First paid checkoutsubscription.activated
Recurring renewal chargesubscription.renewed
Paused → resumedsubscription.unpaused
Cancelled → reinstated before ends_atsubscription.reactivated
Past-due → collectedsubscription.renewed
Trial → payingmember.converted
Access code / cardless trialsubscription.created

A Stripe subscription that begins in a trial still emits subscription.activated at acquisition, because the provider creates the subscription at that moment. The later trial-to-paid transition emits member.converted only.

This is the paid-acquisition event. If you only subscribe to one subscription event for a paying audience, subscribe to this one, not subscription.created, which never fires for paid checkouts.

data.provider is never access_code on this event; code redemptions emit subscription.created instead.

Caveats

  • Once per subscription. Stripe and PayPal de-duplicate with a persistent guard key; the remaining providers emit only on the non-renewal branch of their payment handler. Renewals never re-emit it.
  • To capture every acquisition path (paid, comped code, and cardless trial) subscribe to both subscription.activated and subscription.created, then de-duplicate on data.subscription_id.
  • Paid acquisitions do not emit member.joined. That event is access-code-only. Use subscription.activated as the paid-audience join signal.
  • payment.succeeded fires for the same charge and carries the amount, currency, and external payment id, which this event does not.
  • The POST /v1/webhook-endpoints/{endpoint}/test endpoint sends a synthetic subscription.created payload, never subscription.activated. Testing an endpoint does not exercise this event.

Related events

  • subscription.created: the zero-payment acquisition equivalent.
  • payment.succeeded: the charge behind this activation.
  • subscription.renewed: every subsequent cycle.
  • member.converted: trial-to-paying transition.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.trial_started

WEBHOOK

Trial-enabled plan starts free window.

When this fires

A subscriber starts a trial on a trial-enabled plan. Three paths emit it: a cardless trial, an access-code redemption against a trial plan, or a Stripe checkout that begins in a trial window.

Trial checkouts through the other providers (PayPal, Paystack, Razorpay, Skrill, CeyPay, CoinPayments) do not currently emit this event; only Stripe reports the trialing status transition back to Subscriby.

Pairs with member.trial_joined: both fire together when a subscriber starts a trial on the cardless-trial and access-code paths.

The data keys differ by path. Absent keys are omitted entirely, not sent as null.

Caveats

  • On the cardless-trial and access-code paths this is paired with subscription.created and member.trial_joined for the same subscription_id. On the Stripe path it is paired with subscription.activated instead, and no member.* join event fires.
  • Plans with trial_days = 0 skip this event entirely.

Related events

  • subscription.trial_converting: fires 24h before trial_ends_at.
  • subscription.trial_expired: fires if no conversion occurs.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.trial_converting

WEBHOOK

Trial about to convert. Fires 24h before `trial_ends_at`.

When this fires

Fires 24 hours before trial_ends_at to give consumers a window to send conversion-reminder messaging. Emitted once per trial, by the hourly trial-conversion notifier.

Fires exactly once per trial, 24 hours before trial_ends_at.

Caveats

  • Idempotency is enforced server-side: each trial receives this event at most once.
  • If trial_ends_at is moved closer than 24h after the trial has already started, the notice may not fire.

Related events

  • subscription.trial_started: predecessor.
  • subscription.activated, member.converted: fire on successful conversion.
  • subscription.trial_expired: alternative path if conversion fails.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.trial_expired

WEBHOOK

Trial ended without conversion.

When this fires

A trial ends without conversion. Emitted alongside subscription.expired for the same subscription.

Caveats

  • Successful conversions fire subscription.activated and member.converted instead.
  • Expect subscription.expired and member.churned to follow for the same subscriber.

Related events

  • subscription.trial_started: predecessor.
  • subscription.expired: fires alongside.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.renewed

WEBHOOK

Recurring billing successfully charged the subscriber.

When this fires

Recurring billing successfully charges the subscriber and the subscription is renewed for another period.

Caveats

  • A subscription.renewed is always paired with a payment.succeeded for the same charge.
  • Currency may differ from the plan's nominal currency for providers that auto-convert at the gateway.

Related events

  • payment.succeeded: paired payment event.
  • subscription.past_due, subscription.unpaid: failure paths.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.reactivated

WEBHOOK

Cancelled subscription re-activated before `ends_at`.

When this fires

A previously cancelled subscription is reactivated before its ends_at. The subscription returns to the active state and the next billing cycle resumes.

Caveats

  • Reactivation is only possible while ends_at is in the future. After expiration, a new subscription must be created instead.
  • Pairs with a renewed provider subscription for paid plans; the next charge will follow normal cadence.

Related events

  • subscription.cancelled: predecessor.
  • subscription.expired: alternative path if reactivation does not occur.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.paused

WEBHOOK

A member's access was suspended. Billing is unaffected and continues on schedule.

When this fires

A creator suspended a member's access. payment_status becomes paused, paused_at is stamped, and the member is removed from every linked resource.

This is an access pause, not a billing pause. The member's payment provider keeps charging them on schedule. Subscriby does not pause collection, suspend the PayPal agreement, or otherwise hold the charge. If you need billing to stop, cancel instead.

The split is deliberate: Subscriby settles through seven providers and only some can hold a recurring charge at all, so a pause meaning "stop billing" would work on some providers and silently not on others. Access is something Subscriby controls directly, so it behaves identically everywhere.

Before 1 September 2026 this event fired without anything happening: no provider was called and no access was removed. If you built on the old behaviour, note that a paused member now genuinely loses access.

Caveats

  • Pausing does not change ends_at, and does not stop the clock. The member is still being billed, so a long pause costs them money for access they do not have. Tell them, or cancel instead.
  • Access removal is queued, one call per linked resource, so it completes shortly after this event rather than atomically with it.
  • Pausing does not detach resources, so no member.resource_removed events follow. Revocation happens only on expiry or cancellation.

Related events

  • subscription.unpaused: paired transition.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.unpaused

WEBHOOK

Paused subscription resumes; resource invite links re-issued.

When this fires

A suspended member has their access restored, with fresh invite links: an invite link revoked on pause cannot be un-revoked.

Billing is not mentioned here because it never stopped: pausing suspends access only, so there is nothing on the provider side to resume.

Caveats

  • Expect member.resource_added entries as resources are re-attached. subscription.activated does not follow an unpause; it fires only once, at first paid acquisition.
  • Renewal cadence resumes from the original ends_at boundary, not the unpause moment.

Related events

  • subscription.paused: paired transition.
  • member.resource_added: re-grant signal.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.past_due

WEBHOOK

Billing fails but grace period is active.

When this fires

A scheduled charge fails but the subscription remains within its grace window. The platform will continue to attempt collection.

Coverage is partial: only Stripe and Razorpay report the past-due transition back to Subscriby. Failed renewals on PayPal, Paystack, Skrill, CeyPay, and CoinPayments emit payment.failed without a matching subscription.past_due, so treat payment.failed as the reliable cross-provider signal.

Caveats

  • Pairs with a payment.failed event for the underlying charge.
  • If retries succeed, subscription.renewed follows. If grace expires, subscription.unpaid fires instead.

Related events

  • payment.failed: paired payment event.
  • subscription.unpaid: grace-window terminal state.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.unpaid

WEBHOOK

Billing permanently failed; grace expired.

When this fires

A subscription's grace period ends without successful collection. The provider has given up retrying. Resource access is typically revoked shortly after.

This event is emitted for Stripe only; it depends on the provider reporting an unpaid subscription status. On every other provider, an abandoned subscription surfaces as subscription.expired once ends_at passes, with no preceding subscription.unpaid.

Caveats

  • After this event, the subscription is non-recoverable on its current terms; the subscriber must restart with a new subscription.
  • Expect subscription.expired and member.churned to follow.

Related events

  • subscription.past_due: predecessor inside the grace window.
  • subscription.expired: terminal state.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.cancelled

WEBHOOK

Cancellation recorded; access continues until `ends_at`.

When this fires

Cancellation is recorded by the subscriber, by the creator, or by the payment provider (a gateway-side cancellation, or a terminal payment failure on CeyPay, CoinPayments or Skrill). If the paid period still has time left, the subscription stays active and the subscriber keeps access until ends_at, after which subscription.expired fires. If no paid period remains, ends_at is set to the cancellation moment and resource access is revoked straight away.

Caveats

  • Cancellation is reversible until ends_at; see subscription.reactivated.
  • A renewal does not occur after cancellation; subscription.renewed will not fire.

Related events

  • subscription.expired: fires when the period ends.
  • subscription.reactivated: reverse path.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.expired

WEBHOOK

`ends_at` reached; access revoked.

When this fires

The subscription's ends_at has passed. Resource access is revoked and the subscription transitions to its terminal state.

Caveats

  • Pairs with member.churned when this is the subscriber's last active subscription.
  • Resource access is revoked as part of expiry; expect member.resource_removed events for each granted resource.

Related events

  • subscription.cancelled, subscription.unpaid, subscription.trial_expired: predecessors.
  • member.churned: paired member-level event.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.refunded

WEBHOOK

Refund recorded against a subscription.

When this fires

A full subscription-level refund settles. The subscription is always expired as a result: resource access is revoked and subscription.expired (plus member.churned when this was the subscriber's last active subscription) follows for the same subscription.

Fires only for a settled refund. A refund a provider has queued but not yet paid out raises nothing; access is never revoked for money that has not actually moved.

Caveats

  • Emitted by Stripe, PayPal, Paystack, Razorpay and Skrill. CoinPayments and CeyPay expose no refund notification, so a refund taken there is invisible to this event.
  • A partial refund raises payment.refunded only. This event means the whole charge came back, and access is revoked with it.
  • Skrill reports a chargeback rather than a merchant refund, and only if the creator's Skrill account is configured to post one.
  • Subscriby expires the subscription itself on a full refund; it does not wait for the provider's own cancellation to arrive.
  • For per-payment refunds (no subscription mutation), see payment.refunded.

Related events

  • payment.refunded: payment-level analogue.
  • subscription.cancelled: often paired in practice.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.upgraded

WEBHOOK

Subscriber moved to a higher-priced plan.

When this fires

A subscriber is switched to a higher-priced plan on the same project. The plan assignment, currency, and stored price on the Subscriby subscription record are updated, and this event reports the move.

The switch does not itself perform a provider-side pro-ration or issue a charge. Any billing adjustment is whatever the provider does on the next cycle.

Caveats

  • Direction is decided by comparing the two plan prices, normalised to USD, at switch time. Only a strictly higher new price emits subscription.upgraded; an equal-price switch emits subscription.downgraded, which is worth guarding for if you offer same-price plan swaps.
  • Trial windows do not carry across switches; if the destination plan has a trial it does not start.

Related events

  • subscription.downgraded: opposite direction.
  • payment.succeeded: the next successful charge on the new plan.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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.

subscription.downgraded

WEBHOOK

Subscriber moved to a lower-priced plan.

When this fires

A subscriber is switched to a lower-priced plan on the same project. The plan assignment, currency, and stored price on the Subscriby subscription record are updated, and this event reports the move.

The switch does not itself perform a provider-side pro-ration or issue a credit. Any billing adjustment is whatever the provider does on the next cycle.

Caveats

  • No credit or refund is issued by this action. If you owe subscribers a mid-cycle credit on downgrade, apply it yourself through the provider.
  • Direction is decided by comparing the two plan prices, normalised to USD. Anything that is not strictly more expensive lands here, so a switch between two equally-priced plans emits this event, not subscription.upgraded.
  • Resource access tied to the higher tier may be revoked on the next renewal cycle.

Related events

  • subscription.upgraded: opposite direction.
  • member.resource_removed: emitted when premium-tier resources are detached.

Ability to subscribe

A token needs this to subscribe an endpoint to the event.

Header Parameters

SB-Signature*string

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=.

SB-Event-Id*string

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.

SB-Event-Name*string

The event name, the same as the envelope's type.

Content-Type*string

Always application/json.

User-Agent*string

Always Subscriby-Webhooks/1.0.

Payload

JSONWhat Subscriby posts to your endpoint

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?

Version

On this page

Subscriby is a product
designed by you — for you.
No boardroom full of executives deciding what we ships next. Our roadmap always shaped by you with your feedback.

Share feedback or a request