Webhook Events Reference
All events that can be subscribed to via POST /apps/subscribe or POST /apps/{client_id}/subscribe.
Each webhook delivery includes an eventName field matching the event string below. The payload data object contains the resource that triggered the event.
Message Events
| Event | Description |
|---|
message.initializing | A message was started and is still initializing (no audio yet). Its conversation_sequence is assigned at start. message.posted.to.channel follows once processing completes; if the creator cancels instead, message.deleted fires. |
message.posted.to.channel | A message was posted to a conversation. Fires when a message is fully processed (transcription, AI enrichment, etc.). This is the primary event for bots and integrations that react to incoming messages. |
message.attachment.added | Files or links were added to a message that was already fully processed (ACTIVE). Use this to catch the client race where attachments land after message.posted.to.channel. Voice agents subscribe to this. |
message.attachment.uploaded | A file attachment's bytes were verified in S3 after the client reported status: Uploaded via PUT /messages/:messageId/attachment/:attachmentId. Fires only when a client reports the upload and the object is present in storage — the server does not poll S3 on its own. Voice agents use this as the fast path to unblock a turn waiting for attachment readiness. |
message.voicememo.created | A voice memo was recorded. Fires after a standalone voice memo (not part of a channel conversation) has been created. |
message.finished | A message has finished all processing (transcription, AI enrichment, etc.) and is fully complete across both conversation messages and voice memos. The relevant message.posted.to.channel or message.voicememo.created event will also fire. |
message.deleted | A message was deleted by its creator or an admin. |
message.label.added | A label was applied to a message. If the label is a workspace-level label, the event is delivered to workspace admins in addition to the user who applied it. |
AI Events
| Event | Description |
|---|
ai.prompt.response.generated | A response was generated from a built-in AI prompt. If the prompt is workspace-level, the event is delivered to workspace admins as well as the user who triggered the prompt. |
Action Item Events
| Event | Description |
|---|
action-item.created | A new action item was created. |
action-item.updated | An existing action item was updated. |
action-item.deleted | An action item was deleted. |
action-item.status.changed | The status of an action item changed (e.g. open → completed). |
Conversation (Channel) Events
| Event | Description |
|---|
channel.created | A new conversation was created. |
channel.deleted | A conversation was deleted. |
channel.users.added | One or more users were added to a conversation by another user. |
channel.user.joined | A user joined a conversation on their own (e.g. accepted an invitation or joined a public channel). |
channel.user.left | A user voluntarily left a conversation. |
channel.user.removed | A user was removed from a conversation by another user. |
channel.ai-summary.generated | An AI-generated summary was produced for a conversation. |
Async Meeting Events
These events fire during the lifecycle of an async meeting channel.
| Event | Description |
|---|
channel.async-check.mid | The async meeting has reached its midpoint checkpoint. |
channel.async-check.ending | The async meeting is nearing its deadline. |
channel.async.ended | The async meeting has ended. |
channel.async.extended | The async meeting deadline was extended. |
channel.async.shortened | The async meeting deadline was shortened. |
Workspace Events
| Event | Description |
|---|
workspace.user.joined | A user joined a workspace (e.g. accepted an invite link). |
workspace.user.added | A user was added to a workspace by an admin. |
workspace.user.left | A user voluntarily left a workspace. |
workspace.user.removed | A user was removed from a workspace by an admin. |
workspace.findable-channel.created | A public (findable) channel was created in a workspace. |
Notes
- Who receives a webhook: Webhooks are sent to the app subscribers who are participants in the affected resource (conversation, workspace, etc.). For workspace-level events (workspace-level AI prompts, workspace-level labels), workspace admins also receive the event.
- Filtering: Use
subscription_filters to narrow which events are delivered. See how-to-register-for-webhooks.md for available filter keys.
- Default subscription: If you do not specify
subscriptions when calling POST /apps/subscribe, all events are subscribed by default.
- Webhook payload The payload structure varies by event type. See the cv-contracts here for the exact structure: https://github.com/PhononX/cv-contracts/tree/main/src/schemas/webhook