Sign in

Webhook events

Liveblocks events

An event occurs when a change is made to Liveblocks data. Each endpoint you provide in the webhooks dashboard listens to all events by default but can be easily configured to only listen to a subset by updating the Message Filtering section.

To configure an endpoint, verify requests, and test locally, read the Webhooks platform guide.

The Event Catalog in the webhooks dashboard provides a list of events available for subscription, along with their schema.

Events available for use include:

  • StorageUpdated
  • UserEntered/UserLeft
  • RoomCreated/RoomDeleted
  • YDocUpdated
  • CommentCreated/CommentEdited/CommentDeleted/CommentMetadataUpdated
  • CommentReactionAdded/CommentReactionRemoved
  • ThreadCreated/ThreadDeleted/ThreadMetadataUpdated
  • Notification

More events will come later, such as:

  • MaxConnectionsReached

UserEnteredEvent

When a user connects to a room, an event is triggered, indicating that the user has entered. The numActiveUsers field shows the number of users in the room after the user has joined. This event is not throttled.

// Schematype UserEnteredEvent = {  type: "userEntered";  data: {    projectId: string;    roomId: string;    connectionId: number;    userId: string | null;    userInfo: Record<string, any> | null;    enteredAt: string;    numActiveUsers: number;  };};
// Exampleconst userEnteredEvent = { type: "userEntered", data: { projectId: "my-project-id", roomId: "my-room-id", connectionId: 4, userId: "a-user-id", userInfo: null, enteredAt: "2021-10-06T01:45:56.558Z", numActiveUsers: 8, },};

UserLeftEvent

A user leaves a room when they disconnect from a room, which is when this event is triggered. The numActiveUsers field represents the number of users in the room after the user has left. This event, like UserEntered, is not throttled.

// Schematype UserLeftEvent = {  type: "userLeft";  data: {    projectId: string;    roomId: string;    connectionId: number;    userId: string | null;    userInfo: Record<string, any> | null;    leftAt: string;    numActiveUsers: number;  };};
// Exampleconst userLeftEvent = { type: "userLeft", data: { projectId: "my-project-id", roomId: "my-room-id", connectionId: 4, userId: "a-user-id", userInfo: { name: "John Doe", }, leftAt: "2021-10-06T01:45:56.558Z", numActiveUsers: 7, },};

StorageUpdatedEvent

Storage is updated when a user writes to Storage. This event is throttled at 60 seconds and, as such, may not be triggered for every write.

For example, if a user writes to Storage at 1:00 pm sharp, the StorageUpdatedEvent event will be triggered shortly after. If the user writes to Storage again at 1:00 pm and 2 seconds, the StorageUpdatedEvent event will be triggered 60 seconds after the first event was sent, around 1:01 pm.

On Enterprise plans we can increase the throttle rate.

// Schematype StorageUpdatedEvent = {  type: "storageUpdated";  data: {    roomId: string;    projectId: string;    updatedAt: string;  };};
// Exampleconst storageUpdatedEvent = { type: "storageUpdated", data: { projectId: "my-project-id", roomId: "my-room-id", updatedAt: "2021-10-06T01:45:56.558Z", // 👈 time of the last write },};

RoomCreatedEvent

An event is triggered when a room is created. This event is not throttled. There are two ways for rooms to be created:

  • By calling the create room API
  • When a user connects to a room that does not exist
// Schematype RoomCreatedEvent = {  type: "roomCreated";  data: {    projectId: string;    roomId: string;    createdAt: string;  };};
// Exampleconst roomCreatedEvent = { type: "roomCreated", data: { projectId: "my-project-id", roomId: "my-room-id", createdAt: "2021-10-06T01:45:56.558Z", },};

RoomDeletedEvent

An event is triggered when a room is deleted. This event is not throttled.

// Schematype RoomDeletedEvent = {  type: "roomDeleted";  data: {    projectId: string;    roomId: string;    deletedAt: string;  };};
// Exampleconst roomDeletedEvent = { type: "roomDeleted", data: { projectId: "my-project-id", roomId: "my-room-id", deletedAt: "2021-10-06T01:45:56.558Z", },};

YDocUpdatedEvent

Yjs document is updated when a user makes a change to a Yjs doc connected to a room. This event is throttled at sixty seconds and, as such, may not be triggered for every write.

For example, if a user updates a Yjs document at 1:00 pm sharp, the YDocUpdatedEvent event will be triggered shortly after. If the user writes to the Yjs document again at 1:00 pm and 2 seconds, the YDocUpdatedEvent event will be triggered 60 seconds after the first event was sent, around 1:01 pm

On Enterprise plans we can increase the throttle rate.

// Schematype YDocUpdatedEvent = {  type: "ydocUpdated";  data: {    projectId: string;    roomId: string;    updatedAt: string;  };};
// Exampleconst ydocUpdatedEvent = { type: "ydocUpdated", data: { projectId: "my-project-id", roomId: "my-room-id", updatedAt: "2013-06-26T19:10:19Z", },};

CommentCreatedEvent

An event is triggered when a comment is created. This event is not throttled.

// Schematype CommentCreatedEvent = {  type: "commentCreated";  data: {    projectId: string;    roomId: string;    threadId: string;    commentId: string;    createdAt: string;    createdBy: string;  };};
// Exampleconst commentCreatedEvent = { type: "commentCreated", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", commentId: "my-comment-id", createdAt: "2021-10-06T01:45:56.558Z", createdBy: "my-user-id", },};

CommentEditedEvent

An event is triggered when a comment is edited. This event is not throttled.

// Schematype CommentEditedEvent = {  type: "commentEdited";  data: {    projectId: string;    roomId: string;    threadId: string;    commentId: string;    editedAt: string;  };};
// Exampleconst commentEditedEvent = { type: "commentEdited", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", commentId: "my-comment-id", editedAt: "2021-10-06T01:45:56.558Z", },};

CommentDeletedEvent

An event is triggered when a comment is deleted. This event is not throttled.

// Schematype CommentDeletedEvent = {  type: "commentDeleted";  data: {    projectId: string;    roomId: string;    threadId: string;    commentId: string;    deletedAt: string;  };};
// Exampleconst commentDeletedEvent = { type: "commentDeleted", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", commentId: "my-comment-id", deletedAt: "2021-10-06T01:45:56.558Z", },};

CommentReactionAddedEvent

An event is triggered when a reaction is added to a comment. This event is not throttled.

// Schematype CommentReactionAddedEvent = {  type: "commentReactionAdded";  data: {    projectId: string;    roomId: string;    threadId: string;    commentId: string;    emoji: string;    addedAt: string;    addedBy: string;  };};
// Exampleconst commentReactionAddedEvent = { type: "commentReactionAdded", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", commentId: "my-comment-id", emoji: "👍", addedAt: "2021-10-06T01:45:56.558Z", addedBy: "my-user-id", },};

CommentReactionRemovedEvent

An event is triggered when a reaction is removed from a comment. This event is not throttled.

// Schematype CommentReactionRemovedEvent = {  type: "commentReactionRemoved";  data: {    projectId: string;    roomId: string;    threadId: string;    commentId: string;    emoji: string;    removedAt: string;    removedBy: string;  };};
// Exampleconst commentReactionRemovedEvent = { type: "commentReactionRemoved", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", commentId: "my-comment-id", emoji: "👍", removedAt: "2021-10-06T01:45:56.558Z", removedBy: "my-user-id", },};

ThreadCreatedEvent

An event is triggered when a thread is created. This event is not throttled.

// Schematype ThreadCreatedEvent = {  type: "threadCreated";  data: {    projectId: string;    roomId: string;    threadId: string;    createdAt: string;    createdBy: string;  };};
// Exampleconst threadCreatedEvent = { type: "threadCreated", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", createdAt: "2021-10-06T01:45:56.558Z", createdBy: "my-user-id", },};

ThreadDeletedEvent

An event is triggered when a thread is deleted. This event is not throttled. A thread is deleted when all comments in the thread are deleted or when the thread is manually deleted.

// Schematype ThreadDeletedEvent = {  type: "threadDeleted";  data: {    projectId: string;    roomId: string;    threadId: string;    deletedAt: string;  };};
// Exampleconst threadDeletedEvent = { type: "threadDeleted", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", deletedAt: "2021-10-06T01:45:56.558Z", },};

ThreadMetadataUpdatedEvent

An event is triggered when a thread metadata is updated. This event is not throttled.

// Schematype ThreadMetadataUpdatedEvent = {  type: "threadMetadataUpdated";  data: {    projectId: string;    roomId: string;    threadId: string;    updatedAt: string;    updatedBy: string;  };};
// Exampleconst threadMetadataUpdatedEvent = { type: "threadMetadataUpdated", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", updatedAt: "2021-10-06T01:45:56.558Z", updatedBy: "my-user-id", },};

CommentMetadataUpdatedEvent

An event is triggered when a comment’s metadata is updated. This event is not throttled.

// Schematype CommentMetadataUpdatedEvent = {  type: "commentMetadataUpdated";  data: {    projectId: string;    roomId: string;    threadId: string;    commentId: string;    updatedAt: string;    updatedBy: string;  };};
// Exampleconst commentMetadataUpdatedEvent = { type: "commentMetadataUpdated", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", commentId: "my-comment-id", updatedAt: "2021-10-06T01:45:56.558Z", updatedBy: "my-user-id", },};

ThreadMarkedAsResolvedEvent

An event is triggered when a thread is marked as resolved. This event is not throttled.

// Schematype ThreadMarkedAsResolvedEvent = {  type: "threadMarkedAsResolved";  data: {    projectId: string;    roomId: string;    threadId: string;    updatedAt: string;    updatedBy: string;  };};
// Exampleconst threadMarkedAsResolvedEvent = { type: "threadMarkedAsResolved", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", updatedAt: "2021-10-06T01:45:56.558Z", updatedBy: "my-user-id", },};

ThreadMarkedAsUnresolvedEvent

An event is triggered when a thread is marked as unresolved. This event is not throttled.

// Schematype ThreadMarkedAsUnresolvedEvent = {  type: "threadMarkedAsUnresolved";  data: {    projectId: string;    roomId: string;    threadId: string;    updatedAt: string;    updatedBy: string;  };};
// Exampleconst threadMarkedAsUnresolvedEvent = { type: "threadMarkedAsUnresolved", data: { projectId: "my-project-id", roomId: "my-room-id", threadId: "my-thread-id", updatedAt: "2021-10-06T01:45:56.558Z", updatedBy: "my-user-id", },};

NotificationEvent

Notification events are designed to help you create notification emails for your users. By default, they’re triggered 30 minutes after an activity occurs, but this number can be modified in your dashboard inside a project’s settings.

This webhook event is triggered by both Liveblocks and custom notification kinds, as detailed below.

Thread notification

When using Comments, an event is triggered 30 minutes after a user has been mentioned or replied to in a thread, and has not seen the thread. It will also be triggered if the user has subscribed to the thread and has not seen the thread. The event won’t be triggered if the user has seen the thread or unsubscribed from the room’s thread notifications. This is the Liveblocks thread notification kind.

// Schematype ThreadNotificationEvent = {  type: "notification";  data: {    channel: "email";    kind: "thread";    projectId: string;    roomId: string;    userId: string;    threadId: string;    inboxNotificationId: string;    // Date representing the time when the webhook event was created.    createdAt: string;    // Date representing the time when the notification itself was created.    triggeredAt: string;  };};
// Exampleconst threadNotificationEvent = { type: "notification", data: { channel: "email", kind: "thread", projectId: "my-project-id", roomId: "my-room-id", userId: "my-user-id", threadId: "my-thread-id", inboxNotificationId: "my-inbox-notification-id", createdAt: "2021-10-06T01:45:56.558Z", triggeredAt: "2021-10-06T01:50:56.558Z", },};

If you want to easily identify this event in your code then you can use the type guard isThreadNotificationEvent.

TextMention notification

When using Text editor, an event is triggered 30 minutes after a user has been mentioned in a text and has not seen the text mention. This is the Liveblocks textMention notification kind.

// Schematype TextMentionNotificationEvent = {  type: "notification";  data: {    channel: "email";    kind: "textMention";    projectId: string;    roomId: string;    userId: string;    mentionId: string;    inboxNotificationId: string;    // Date representing the time when the webhook event was created.    createdAt: string;    // Date representing the time when the notification itself was created.    triggeredAt: string;  };};
// Exampleconst textMentionNotificationEvent = { type: "notification", data: { channel: "email", kind: "textMention", projectId: "my-project-id", roomId: "my-room-id", userId: "my-user-id", mentionId: "my-mention-id", inboxNotificationId: "my-inbox-notification-id", createdAt: "2021-10-06T01:45:56.558Z", triggeredAt: "2021-10-06T01:50:56.558Z", },};

If you want to easily identify this event in your code then you can use the type guard isTextMentionNotificationEvent.

Custom notification

An event is triggered 30 minutes after the user has been notified of a custom event and has not seen the notification. All custom notification kinds are prefixed with $ and are manually by you on the server. Learn more about triggering custom notifications.

// Schematype CustomNotificationEvent = {  type: "notification";  data: {    channel: "email";    kind: "$yourKind"; // Can be any string starting with "$" as defined by the user    projectId: string;    roomId: string | null;    userId: string;    inboxNotificationId: string;    // Date representing the time when the webhook event was created.    createdAt: string;    // Date representing the time when the notification itself was created.    triggeredAt: string;  };};
// Exampleconst customNotificationEvent = { type: "notification", data: { channel: "email", kind: "$fileUpload", projectId: "my-project-id", roomId: "my-room-id", userId: "my-user-id", inboxNotificationId: "my-inbox-notification-id", createdAt: "2021-10-06T01:45:56.558Z", triggeredAt: "2021-10-06T01:50:56.558Z", },};

If you want to easily identify this event in your code then you can use the type guard isCustomNotificationEvent.