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

# Creator Messages

> creator.message.received, sent, read, deleted, and reaction events for a creator's direct messages.

These events mirror a creator's direct-message activity in real time. They are
the successor to the legacy `message.received`, `message.sent`, and
`message.read` events, plus new `deleted` and `reaction` events.

| Event (`type`)             | `data.object`      | Fires when                                                                |
| -------------------------- | ------------------ | ------------------------------------------------------------------------- |
| `creator.message.received` | message            | The creator receives an inbound message from a fan                        |
| `creator.message.sent`     | message            | An outbound creator → fan message is sent (UI, agency, automation, or AI) |
| `creator.message.read`     | fan\_message\_read | The creator marks a fan's messages as read                                |
| `creator.message.deleted`  | message            | A message is unsent/deleted                                               |
| `creator.message.reaction` | reaction           | A reaction is added to a message                                          |

All message events require the `read:chat` scope. Delivered in the
[Standard-Webhooks envelope](/docs/creator/overview#event-envelope); the fields below
describe the `data` object.

<Note>
  Since 2026-07-15, **`creator.message.received` carries the message content** —
  `text`, `media_uuids`, `price`, `tip` and more. `creator.message.sent` and
  `creator.message.deleted` remain metadata-only: for those, use the
  [chat API](/docs/api-reference/get-messages-from-a-chat) to fetch content. See
  [Content fields](#content-fields) for exactly which event carries what.

  The conversation is addressed by the fan (`fan.uuid`); there is no separate
  chat id.
</Note>

<Warning>
  Two payload behaviours that commonly break integrations:

  * **Keys are `snake_case`.** `media_uuids`, `message_type`, `is_muted`,
    `unread_messages_count`, `is_automated` — *not* `mediaUuids`, `messageType`,
    `isMuted`. The deprecated flat
    [`message.received`](/docs/webhooks/message-received) used camelCase; the
    `creator.*` envelope does not.
  * **Optional fields are omitted, not nulled.** An absent value has no key at
    all — it is never sent as `null` or as an empty array. A message with no
    media has no `media_uuids` key, so treat an absent key as empty rather than
    reading `payload.data.media_uuids.length`.
</Warning>

## Message resource

Used by `creator.message.received`, `creator.message.sent`, and
`creator.message.deleted`.

### Core fields

Always present on all three events.

| Field        | Type           | Description                                                                             |
| ------------ | -------------- | --------------------------------------------------------------------------------------- |
| `object`     | string         | Always `"message"`                                                                      |
| `uuid`       | string         | The message's unique identifier                                                         |
| `sender`     | string         | `creator` or `fan`. Always `creator` on `creator.message.sent`                          |
| `created_at` | string \| null | ISO 8601 time the message was created. Always `null` on `creator.message.deleted`       |
| `deleted_at` | string \| null | ISO 8601 unsend time. Set on `creator.message.deleted`, `null` on `received` and `sent` |
| `creator`    | object         | `{ uuid }` of the creator who owns the conversation                                     |
| `fan`        | object         | The conversation counterpart — see [Fan object](#fan-object)                            |
| `metadata`   | object         | Your passthrough metadata map                                                           |

### Content fields

`creator.message.received` carries the message itself. Every field here is
optional in the sense described above: **when the value does not apply, the key
is absent from the payload** — not `null`, not `[]`.

| Field                   | Type      | Present on         | Description                                                                                                                                            |
| ----------------------- | --------- | ------------------ | ------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `text`                  | string    | `received`         | The message body. Absent when the message has no text (e.g. media-only)                                                                                |
| `message_type`          | string    | `received`, `sent` | Platform message type, e.g. `SINGLE_RECIPIENT`, `BROADCAST`, `TIP`, `LOCKED_MESSAGE_UNLOCKED`, `VOICE_CALL`, or an `AUTOMATED_*` / `CHAT_TEXT_*` value |
| `is_muted`              | boolean   | `received`         | Whether the creator has muted this fan                                                                                                                 |
| `media_uuids`           | string\[] | `received`         | Ordered media UUIDs on the message, including its preview. Absent when the message has no media                                                        |
| `price`                 | integer   | `received`         | Unlock price in minor units (cents) for a pay-to-view message. Absent when the message is not a paid unlock                                            |
| `tip`                   | object    | `received`         | `{ price, status, transaction_order_id }` for a `TIP` message. Absent otherwise                                                                        |
| `is_automated`          | boolean   | `received`         | `true` when the message was sent by an automation                                                                                                      |
| `unread_messages_count` | integer   | `received`         | The creator's unread count for this conversation, including this message                                                                               |

<Note>
  `creator.message.sent` carries `message_type` and nothing else from this
  table — no `text`, `media_uuids`, `price`, `tip`, `is_muted`,
  `is_automated`, or `unread_messages_count`. `creator.message.deleted` carries
  none of them. Fetch content for those events from the
  [chat API](/docs/api-reference/get-messages-from-a-chat).
</Note>

### Fan object

| Field          | Type           | Present on         | Description                                                                             |
| -------------- | -------------- | ------------------ | --------------------------------------------------------------------------------------- |
| `uuid`         | string         | all                | The counterpart's user UUID. This also addresses the conversation                       |
| `email`        | null           | all                | **Always `null`** on message events. Present for shape parity only; do not rely on it   |
| `display_name` | string         | `received`, `sent` | The counterpart's display name. Absent when the identity lookup does not resolve it     |
| `handle`       | string         | `received`, `sent` | The counterpart's public handle. Absent when the identity lookup does not resolve it    |
| `avatar_url`   | string \| null | `received`         | Avatar URL. `null` when they have no avatar; absent when `display_name` did not resolve |

`creator.message.deleted` sends `fan` as `{ uuid, email: null }` only — no
`display_name`, `handle`, or `avatar_url`.

### Example: `creator.message.received`

A pay-to-view message with text and two media attachments:

```json theme={null}
{
  "id": "f1a2b3c4-4444-4a2b-9c3d-aaaaaaaaaaaa",
  "type": "creator.message.received",
  "timestamp": "2026-06-09T08:39:33.139Z",
  "data": {
    "object": "message",
    "uuid": "2f7c5e8a-6d36-4e3a-98d9-9f1b3b0a1a10",
    "sender": "fan",
    "created_at": "2026-06-09T08:39:33.139Z",
    "deleted_at": null,
    "text": "Hey! Loved your latest post 😍",
    "message_type": "SINGLE_RECIPIENT",
    "is_muted": false,
    "media_uuids": [
      "b8c47a91-3f2d-4a55-b7e8-1c9d2e4f5a6b",
      "c1d58b02-4e3e-4b66-c8f9-2d0e3f5a6b7c"
    ],
    "price": 300,
    "is_automated": false,
    "unread_messages_count": 3,
    "creator": { "uuid": "creator-uuid" },
    "fan": {
      "uuid": "fan-uuid",
      "email": null,
      "display_name": "Jane D",
      "handle": "janed",
      "avatar_url": "https://cdn.fanvue.com/avatars/example.jpg"
    },
    "metadata": {}
  }
}
```

A plain text-only message from the same fan omits `media_uuids` and `price`
entirely — the keys are not present at all.

### Example: `creator.message.sent`

The same envelope and `object`, but **not the same shape**: `sender` is always
`creator`, and the only content field is `message_type`.

```json theme={null}
{
  "id": "f1a2b3c4-7777-4a2b-9c3d-aaaaaaaaaaaa",
  "type": "creator.message.sent",
  "timestamp": "2026-06-09T08:41:02.114Z",
  "data": {
    "object": "message",
    "uuid": "9b1c3d4e-5f60-4a7b-8c9d-0e1f2a3b4c5d",
    "sender": "creator",
    "created_at": "2026-06-09T08:41:02.114Z",
    "deleted_at": null,
    "message_type": "SINGLE_RECIPIENT",
    "creator": { "uuid": "creator-uuid" },
    "fan": {
      "uuid": "fan-uuid",
      "email": null,
      "display_name": "Jane D",
      "handle": "janed"
    },
    "metadata": {}
  }
}
```

`creator.message.deleted` carries the core fields only: `sender`, `deleted_at`
set to the unsend time, `created_at` as `null`, and `fan` as
`{ uuid, email: null }`.

## Read-receipt resource

Used by `creator.message.read`. This is a per-conversation read receipt, not a
message entity — it reports counts rather than a message uuid.

| Field                   | Type    | Description                                                                                                                            |
| ----------------------- | ------- | -------------------------------------------------------------------------------------------------------------------------------------- |
| `object`                | string  | Always `"fan_message_read"`                                                                                                            |
| `read_messages_count`   | integer | How many of the fan's messages were just marked read                                                                                   |
| `unread_messages_count` | integer | The creator's remaining unread count for this conversation                                                                             |
| `fan`                   | object  | `{ uuid, email }` of the conversation counterpart. `email` is always `null`; no `display_name` / `handle` / `avatar_url` on this event |
| `creator`               | object  | `{ uuid }` of the creator who read the messages                                                                                        |
| `metadata`              | object  | Your passthrough metadata map                                                                                                          |

### Example: `creator.message.read`

```json theme={null}
{
  "id": "f1a2b3c4-5555-4a2b-9c3d-aaaaaaaaaaaa",
  "type": "creator.message.read",
  "timestamp": "2026-06-09T08:39:33.139Z",
  "data": {
    "object": "fan_message_read",
    "read_messages_count": 3,
    "unread_messages_count": 0,
    "fan": { "uuid": "fan-uuid", "email": null },
    "creator": { "uuid": "creator-uuid" },
    "metadata": {}
  }
}
```

## Reaction resource

Used by `creator.message.reaction`.

| Field          | Type           | Description                                         |
| -------------- | -------------- | --------------------------------------------------- |
| `object`       | string         | Always `"reaction"`                                 |
| `message_uuid` | string         | The message that was reacted to                     |
| `emoji`        | string         | The reaction emoji                                  |
| `actor`        | object         | `{ uuid }` of the user who reacted                  |
| `creator`      | object         | `{ uuid }` of the creator who owns the conversation |
| `created_at`   | string \| null | ISO 8601 time the reaction was added                |
| `metadata`     | object         | Your passthrough metadata map                       |

### Example: `creator.message.reaction`

```json theme={null}
{
  "id": "f1a2b3c4-6666-4a2b-9c3d-aaaaaaaaaaaa",
  "type": "creator.message.reaction",
  "timestamp": "2026-06-09T08:39:33.139Z",
  "data": {
    "object": "reaction",
    "message_uuid": "2f7c5e8a-6d36-4e3a-98d9-9f1b3b0a1a10",
    "emoji": "❤️",
    "actor": { "uuid": "fan-uuid" },
    "creator": { "uuid": "creator-uuid" },
    "created_at": "2026-06-09T08:39:33.139Z",
    "metadata": {}
  }
}
```
