Skip to main content
creator.chat.* events report conversation state rather than message state. One event exists today: It requires the read:chat scope, the same as the message events, and is delivered in the Standard-Webhooks envelope; the fields below describe the data object. It has no legacy flat equivalent.
No message’s read state changes when this fires. Marking a conversation unread flips a conversation-level flag; every message in the thread keeps the read status it already had.If you render read ticks from creator.message.read_by_fan, do not revert them on this event. That is why this is a creator.chat.* event and not a creator.message.* one.

The inbox badge has two halves

The Fanvue sidebar shows a conversation as unread when either of two things is true, and you need both events to mirror it: Render a conversation as unread when the marker is set or unread_messages_count is above zero. Clearing a manual marker on a conversation with no unread messages emits creator.message.read with read_messages_count: 0, which is the marker being cleared rather than a no-op.
Subscribe to both. Taking only creator.chat.marked_unread gives you a badge you can never turn off.

Ordering the two halves

The two halves are not ordered against each other. Each event is published independently, so a mark and a read that happen close together can arrive in either order. Compare the times on the payloads and apply whichever is later, rather than applying whichever landed last:
Both times are stamped when the action was handled, not when the event was published, so they stay put across delivery retries. The envelope timestamp does not; do not order on it.

Chat unread marker resource

The conversation is addressed by fan.uuid; there is no separate chat id, the same as on the message events.

unread_messages_count is usually 0

Marking a conversation unread does not create unread messages, so the count is whatever it already was, and in the common case, a creator flagging a chat they have already read so they remember to come back to it, that is 0. A 0 here does not contradict the event. It is why the badge rule above is an OR rather than a count check. The count is resolved best-effort when the event is built. If that lookup fails the event is still delivered, with 0, rather than being dropped, so treat 0 as “no unread messages, or not resolved” and fall back to GET /chats if you need the exact number.

Fan object

Same shape as the Fan object on the message events, minus avatar_url. The identity lookup is best-effort and runs after the delivery decision, so an absent handle or display_name is a lookup that did not resolve, not a change to the fan’s profile. creator stays a bare { uuid }. The creator is the account you already hold a token for, so this event does not restate their identity.

Delivery

Each event reaches:
  • apps holding read:chat for the creator, and
  • the creator’s connector destination, when one is subscribed.
The two destination kinds resolve independently: a failure to resolve one does not cost the other its delivery.

What does not fire it

  • Marking a conversation that is already unread. The event reports the transition into unread, not the action, so a repeat mark with no read in between emits nothing. Marking, reading, and marking again does emit twice, because the read cleared the marker in between.
  • A fan marking a creator’s chat unread. The event is creator-owned and reports the creator’s own inbox, so a mark by a non-creator produces nothing, even though read:chat is a scope a fan’s app can hold.
  • A conversation going unread because a new message arrived. That is creator.message.received, which already carries unread_messages_count. This event is the deliberate manual mark only.
  • Archiving or muting a conversation. Muting is creator.fan.status_changed; archiving emits nothing today.
  • Internal AI and support conversations, which are never exposed to integrations.

Deduplicating a mark

The event id is a hash of the two parties and marked_at, so it carries an occurrence component and the id alone is a valid idempotency key. A creator who marks a conversation unread, opens it, and marks it unread again gets two events with two ids, with no new message needed in between. See Deduplicating events. This event is not in the read-receipt carve-out that applies to creator.message.read.

Example: creator.chat.marked_unread

A creator flagging a conversation they have already read: