> ## Documentation Index
> Fetch the complete documentation index at: https://api.fanvue.com/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Overview

> Real-time creator.* events for a creator's whole platform activity: payments, subscriptions, messages, engagement, refunds, and disputes.

`creator.*` webhooks notify your backend in real time about activity across a
creator's Fanvue account: on-platform payments, subscriptions, direct messages,
post and message engagement, refunds, and disputes. They are the successor to the
older flat platform events (`purchase.new`, `subscription.new`, `message.received`,
and so on).

Unlike the [checkout webhooks](/checkout/overview), which are scoped to a
creator's checkout-link sales, `creator.*` events cover the creator's whole
platform feed. Each event carries the OAuth scope your app must hold to receive
it — see [Available events](#available-events).

<Note>
  `creator.*` events replace the legacy flat platform events (New Follower,
  Purchase Received, Message Received, etc.). The legacy events are
  **deprecated** but continue to fire during the migration window, so existing
  integrations keep working. New integrations should use `creator.*`. See
  [Migrating from the legacy events](#migrating-from-the-legacy-events).
</Note>

## Setting up and verifying

Setup, testing, and signature verification are the same as for every Fanvue
webhook:

* Add an endpoint and select events in the Developer Area — see
  [Webhooks Overview](/webhooks/webhooks-overview).
* Verify the `X-Fanvue-Signature` header on every request — see
  [Verify Webhook Signatures](/webhooks/signature-verification).

## Amounts and currency

All monetary amounts are integers in the currency's **minor units** (for USD,
cents, so `9999` means `$99.99`). Each resource carries its own `currency` (ISO
4217\), which may be `null` when not yet known.

## Event envelope

Every `creator.*` webhook is delivered as an HTTP `POST` with this envelope:

```json theme={null}
{
  "id": "f1a2b3c4-1111-4a2b-9c3d-aaaaaaaaaaaa",
  "type": "creator.payment.succeeded",
  "timestamp": "2026-06-09T08:39:33.139Z",
  "data": { "object": "payment", "...": "resource fields" }
}
```

* `id`: unique event id, stable across delivery retries (use it to dedupe). Also
  delivered as the Standard-Webhooks `webhook-id`.
* `type`: the event name (one of the topics in [Available events](#available-events)).
* `timestamp`: ISO 8601 time the event was emitted.
* `data`: the resource object. `data.object` tells you the resource type
  (`payment`, `subscription`, `follow`, `message`, `fan_message_read`, `post`,
  `reaction`, `refund`, `dispute`, `fan_status`).

Fields inside `data` are **snake\_case**.

<Note>
  This is the same [Standard-Webhooks
  envelope](/checkout/overview#event-envelope) the checkout events use. The
  legacy flat platform events keep their original flat, camelCase payloads.
</Note>

## Attribution

Payment, subscription, follow, and refund/dispute resources echo two attribution
fields when they were captured on the originating purchase:

* `client_reference_id`: your passthrough reference (`string | null`).
* `metadata`: your passthrough key/value map (`{}` when none was set).

This lets churn, refund, and dispute events carry the same attribution as the
original sale. See [Checkout Attribution](/checkout/attribution) for how these
are set.

## Available events

Each group links to a reference page with full field definitions and example
payloads. The scope column is the OAuth scope your app must hold for the event
to be delivered.

| Event (`type`)                                      | `data.object`      | Scope          | Reference                                         |
| --------------------------------------------------- | ------------------ | -------------- | ------------------------------------------------- |
| `creator.payment.succeeded`                         | `payment`          | `read:creator` | [Payments](/creator/payments)                     |
| `creator.subscription.activated`                    | `subscription`     | `read:creator` | [Subscriptions](/creator/subscriptions)           |
| `creator.subscription.deactivated`                  | `subscription`     | `read:creator` | [Subscriptions](/creator/subscriptions)           |
| `creator.subscription.cancel_at_period_end_changed` | `subscription`     | `read:creator` | [Subscriptions](/creator/subscriptions)           |
| `creator.message.received`                          | `message`          | `read:chat`    | [Messages](/creator/messages)                     |
| `creator.message.sent`                              | `message`          | `read:chat`    | [Messages](/creator/messages)                     |
| `creator.message.read`                              | `fan_message_read` | `read:chat`    | [Messages](/creator/messages)                     |
| `creator.message.deleted`                           | `message`          | `read:chat`    | [Messages](/creator/messages)                     |
| `creator.message.reaction`                          | `reaction`         | `read:chat`    | [Messages](/creator/messages)                     |
| `creator.follow.created`                            | `follow`           | `read:creator` | [Engagement](/creator/engagement)                 |
| `creator.post.liked`                                | `post`             | `read:post`    | [Engagement](/creator/engagement)                 |
| `creator.post.commented`                            | `post`             | `read:post`    | [Engagement](/creator/engagement)                 |
| `creator.refund.created`                            | `refund`           | `read:creator` | [Refunds and disputes](/creator/refunds-disputes) |
| `creator.dispute.flagged`                           | `dispute`          | `read:creator` | [Refunds and disputes](/creator/refunds-disputes) |
| `creator.dispute.created`                           | `dispute`          | `read:creator` | [Refunds and disputes](/creator/refunds-disputes) |
| `creator.fan.status_changed`                        | `fan_status`       | `read:chat`    | [Fan status](/creator/fan-status)                 |

## Migrating from the legacy events

The legacy flat events map onto `creator.*` as follows. The `creator.*` payloads
are richer (full money breakdown, billing reason, attribution) and share one
envelope shape, so a single handler can process the whole domain.

| Legacy event             | Replacement                                         | Notes                                                   |
| ------------------------ | --------------------------------------------------- | ------------------------------------------------------- |
| `follow.new`             | `creator.follow.created`                            | —                                                       |
| `purchase.new`           | `creator.payment.succeeded`                         | `source` is `post`, `message`, or `media`               |
| `tip.new`                | `creator.payment.succeeded`                         | `source` is `tip`                                       |
| `subscription.new`       | `creator.subscription.activated`                    | —                                                       |
| `subscription.cancelled` | `creator.subscription.cancel_at_period_end_changed` | Auto-renew turned off; access continues to `expires_at` |
| `subscription.expired`   | `creator.subscription.deactivated`                  | Access removed; see `deactivation_reason`               |
| `message.received`       | `creator.message.received`                          | —                                                       |
| `message.sent`           | `creator.message.sent`                              | —                                                       |
| `message.read`           | `creator.message.read`                              | —                                                       |

<Note>
  During the migration window both the legacy event and its `creator.*`
  replacement fire. Subscribe to one or the other for a given concern to avoid
  double-processing.
</Note>
