Skip to main content
Two events report whether a fan’s paid fan-experience subscription currently grants access. Your app uses them as a grant and revoke pair to open and close whatever the experience gates. How experiences are priced and paid is on Experience payments. Both require the read:experience scope, not read:creator, and reach only the app that owns the experience (see Delivery). Each event arrives in the envelope, and the tables below describe data. A fan-experience subscription is not a profile subscription. A fan can hold both against the same creator at the same time, plus one per experience. creator.experience_subscription.deactivated says a fan lost access to one experience and nothing about their profile subscription, so revoking profile-gated content on it removes access the fan still pays for. Profile subscriptions ride creator.subscription.* with data.object: "subscription", while these events carry data.object: "experience_subscription". Discriminate on type or data.object.

Access ended, not billing changed

A cancellation is not an access-ended signal. A fan turning auto-renew off keeps access until the period they paid for runs out, and creator.experience_subscription.deactivated fires at that point, not at the moment they cancel. Key every revocation on access_ends_at and on the event arriving. Never key it on cancel_at_period_end being true, and never on expires_at alone, because a refund, chargeback, ban or unpublish ends access mid-period and leaves expires_at in the future. Fan experiences have no intent-to-cancel event. creator.subscription.cancel_at_period_end_changed covers auto-renew changes for profile subscriptions only and has no fan-experience equivalent.

Delivery

Other creator.* events fan out to every app holding the required scope for that creator. Experience subscription events reach only two kinds of recipient:
  • the app that owns the experience, resolved from the subscription’s own app.uuid, and
  • the creator’s connector destinations subscribed to the topic.
An experience subscription belongs to one app, so a creator-wide fan-out would tell app A which fans stopped paying app B. An app that doesn’t own the experience receives nothing.

Experience subscription resource

access_ends_at and expires_at agree only on a period-end cancellation. Every other end_reason revokes mid-period, leaving expires_at the later of the two. access_ends_at < expires_at means the fan lost time they had paid for. These events carry no charge amounts. price is frozen at subscribe time, so it is not the amount of any particular renewal. For what was charged, read GET /insights/earnings and match rows on experienceUuid, which is this payload’s experience.uuid. See Attributing fan-experience revenue.

End reasons

end_reason is always present on creator.experience_subscription.deactivated. A subscription keeps renewing while auto-renew is on and the experience is still sold as a recurring paid experience by an app the creator still has installed. Renewal stops when the experience is unpublished, leaves the paid access mode, is re-priced to a one-off price or its app is uninstalled, and the subscription ends with end_reason: "experience_unavailable". The payload carries no retry state. A payment_failed event means the due charge was declined and access is gone as of access_ends_at, so revoke on it and wait for creator.experience_subscription.activated.

Activation reasons

activation_reason is always present on creator.experience_subscription.activated.
Handling renewal_recovered is required if you revoke on deactivated. A declined renewal revokes access and fires deactivated with end_reason: "payment_failed" before the dunning retries run. A retry that settles pays for the period and restores access. An app that revoked and never re-grants leaves a fan who has paid locked out permanently.

Examples

creator.experience_subscription.deactivated

A cancellation reaching the end of its paid period, so access_ends_at and expires_at agree.
A mid-period revocation, with access_ends_at before expires_at:

creator.experience_subscription.activated

The recovery case, after a payment_failed revocation.

Revoking access on subscription end

Gate the resource on one pair of handlers that revokes on deactivated and grants on activated. Verify the signature first, return 2xx immediately, and do the revocation out of band.
Access can also lapse silently at expires_at. A subscription grants access only while expires_at is in the future. The expiry sweep defers a row when a renewal is still settling, the owning app is suspended or an upstream lookup fails. The fan then loses access on the clock, with no event until a later sweep resolves the row. Expire your own cached grant at expires_at and let activated extend it.

Attributing revenue to an experience

Experience subscription events are access signals, not money events. They don’t fire per charge, so a renewal that keeps a fan’s access produces no event on this topic. Use them to grant and revoke, and read revenue from purchase.new or GET /insights/earnings. Per settled charge. purchase.new carries experienceUuid and experienceAppUuid on purchaseType: "fan_experience" purchases. It covers one-off access purchases only. Recurring subscription charges have no real-time event. Per experience, for reconciliation. GET /insights/earnings reports experienceUuid and experienceAppUuid on every fan-experience charge, and accepts experienceUuid as a filter:
The filter returns every charge and reversal one experience produced, so a filtered total nets out. It needs the read:insights scope, not read:experience. Don’t detect experience revenue with source. A renewal reports source: "renewal", so source=fanExperience returns only first payments and one-off purchases and under-reports recurring experience revenue from the second charge onwards. Filter on experienceUuid, or key on the field being present.