Skip to content
Linq

Webhooks

ModelsExpand Collapse
MessageEventV2 object { id, chat, direction, 10 more }

Unified payload for message webhooks when using webhook_version: "2026-02-03".

This schema is used for message.sent, message.received, message.delivered, and message.read events when the subscription URL includes ?version=2026-02-03.

Key differences from V1 (2025-01-01):

  • direction: “inbound” or “outbound” instead of is_from_me boolean
  • sender_handle: Full handle object for the sender
  • chat: Nested object with id, is_group, and owner_handle
  • Message fields (id, parts, etc.) are at the top level, not nested in message

Timestamps indicate the message state:

  • message.sent: sent_at set, delivered_at=null, read_at=null
  • message.received: sent_at set, delivered_at=null, read_at=null
  • message.delivered: sent_at set, delivered_at set, read_at=null
  • message.read: sent_at set, delivered_at set, read_at set
id: string

Message identifier

formatuuid
chat: object { id, health_status, is_group, owner_handle }

Chat information

id: string

Chat identifier

formatuuid
health_status: object { doc_url, status, updated_at }

[BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.

Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.

See the Chat Health guide for what each status means and how to react.

doc_url: string

Deep-link to the relevant section of the Chat Health guide for this status.

formaturi
status: "HEALTHY" or "AT_RISK" or "CRITICAL" or "OPTED_OUT"

Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.

OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT. The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back in immediately — a reply in any conversation with you counts, the same way the block does.

OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status. Group threads are never marked and are never blocked.

Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code 2024) before the message is queued, across every chat and every line on your account. Nothing is delivered, including a final courtesy message — to send one, set override_optout: true on that single request.

One of the following:
"HEALTHY"
"AT_RISK"
"CRITICAL"
"OPTED_OUT"
updated_at: string

When this status last changed.

formatdate-time
is_group: optional boolean

Whether this is a group chat

owner_handle: optional ChatHandle { id, handle, joined_at, 4 more }

Your phone number’s handle. Always has is_me=true.

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
direction: "inbound" or "outbound"

Message direction - “outbound” if sent by you, “inbound” if received

One of the following:
"inbound"
"outbound"
parts: array of SchemasTextPartResponse { type, value } or SchemasMediaPartResponse { id, filename, mime_type, 3 more } or object { type, value }

Message parts (text and/or media)

One of the following:
SchemasTextPartResponse object { type, value }

A text message part

type: "text"

Indicates this is a text message part

value: string

The text content

SchemasMediaPartResponse object { id, filename, mime_type, 3 more }

A media attachment part

id: string

Unique attachment identifier

formatuuid
filename: string

Original filename

mime_type: string

MIME type of the file

size_bytes: number

File size in bytes

type: "media"

Indicates this is a media attachment part

url: string

Presigned URL for downloading the attachment (expires in 1 hour).

formaturi
Link object { type, value }

A rich link preview part

type: "link"

Indicates this is a rich link preview part

value: string

The URL

sender_handle: ChatHandle { id, handle, joined_at, 4 more }

The handle that sent this message

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
delivered_at: optional string

When the message was delivered. Null if not yet delivered.

formatdate-time
idempotency_key: optional string

Idempotency key for deduplication of outbound messages.

read_at: optional string

When the message was read. Null if not yet read.

formatdate-time
reconciled_at: optional string

Present only when this message was recovered by reconciliation rather than delivered live, and set to the time of that recovery. The field is omitted entirely for normally-delivered messages, which is the overwhelming majority. When present, expect sent_at to be substantially earlier than delivery of this event: the message is genuine but is arriving late and out of real-time order, so treat it as history rather than as a live inbound (for example, suppress auto-replies).

formatdate-time
reply_to: optional object { message_id, part_index }

Reference to the message this is replying to (for threaded replies)

message_id: optional string

ID of the message being replied to

formatuuid
part_index: optional number

Index of the part being replied to

formatint32
minimum0
sent_at: optional string

When the message was sent. Null if not yet sent.

formatdate-time
zero_retention: optional boolean

True when this message was sent on a zero-day-retention line. parts is always empty in that case — Linq never persists this message’s content, so there is nothing to include here, not even a count or type of what was sent.

MessagePayload object { id, created_at, delivered_at, 9 more }

Message content nested within webhook events

id: optional string

Message identifier

formatuuid
created_at: optional string

When the message record was created

formatdate-time
delivered_at: optional string

When the message was delivered

formatdate-time
is_delivered: optional boolean

Whether the message has been delivered

is_read: optional boolean

Whether the message has been read

parts: optional array of SchemasTextPartResponse { type, value } or SchemasMediaPartResponse { id, filename, mime_type, 3 more } or object { type, value }

Message content parts (text and/or media)

One of the following:
SchemasTextPartResponse object { type, value }

A text message part

type: "text"

Indicates this is a text message part

value: string

The text content

SchemasMediaPartResponse object { id, filename, mime_type, 3 more }

A media attachment part

id: string

Unique attachment identifier

formatuuid
filename: string

Original filename

mime_type: string

MIME type of the file

size_bytes: number

File size in bytes

type: "media"

Indicates this is a media attachment part

url: string

Presigned URL for downloading the attachment (expires in 1 hour).

formaturi
SchemasLinkPartResponse object { type, value }

A rich link preview part

type: "link"

Indicates this is a rich link preview part

value: string

The URL

read_at: optional string

When the message was read

formatdate-time
reconciled_at: optional string

Present only when this message was recovered by reconciliation rather than delivered live, and set to the time of that recovery. The field is omitted entirely for normally-delivered messages, which is the overwhelming majority. When present, expect sent_at to be substantially earlier than delivery of this event: the message is genuine but is arriving late and out of real-time order, so treat it as history rather than as a live inbound (for example, suppress auto-replies).

formatdate-time
reply_to: optional object { message_id, part_index }

Reference to the message this is replying to

message_id: optional string

The ID of the message being replied to

formatuuid
part_index: optional number

Index of the message part being replied to (0-based)

formatint32
minimum0
sent_at: optional string

When the message was sent

formatdate-time
updated_at: optional string

When the message record was last updated

formatdate-time
zero_retention: optional boolean

True when this message was sent on a zero-day-retention line. parts is always empty in that case — Linq never persists this message’s content, so there is nothing to include here, not even a count or type of what was sent.

ReactionEventBase object { is_from_me, reaction_type, chat_id, 8 more }
is_from_me: boolean

Whether this reaction was from the owner of the phone number (true) or from someone else (false)

reaction_type: ReactionType

Type of reaction. Standard reactions are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type “custom” with the actual emoji in the custom_emoji field.

One of the following:
"love"
"like"
"dislike"
"laugh"
"emphasize"
"question"
"custom"
chat_id: optional string

Chat identifier (UUID)

custom_emoji: optional string

The actual emoji when reaction_type is “custom”. Null for standard reactions.

Deprecatedfrom: optional string

DEPRECATED: Use from_handle instead. Phone number or email address of the person who added/removed the reaction.

from_handle: optional ChatHandle { id, handle, joined_at, 4 more }

The person who added/removed the reaction as a full handle object

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
message_id: optional string

Message identifier (UUID) that the reaction was added to or removed from

part_index: optional number

Index of the message part that was reacted to (0-based)

formatint32
minimum0
reacted_at: optional string

When the reaction was added or removed

formatdate-time
reaction_id: optional string

Identifier for this reaction.

formatuuid
service: optional ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
SchemasMediaPartResponse object { id, filename, mime_type, 3 more }

A media attachment part

id: string

Unique attachment identifier

formatuuid
filename: string

Original filename

mime_type: string

MIME type of the file

size_bytes: number

File size in bytes

type: "media"

Indicates this is a media attachment part

url: string

Presigned URL for downloading the attachment (expires in 1 hour).

formaturi
SchemasTextPartResponse object { type, value }

A text message part

type: "text"

Indicates this is a text message part

value: string

The text content

MessageSentWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for message.sent events (2026-02-03 format)

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: MessageEventV2 { id, chat, direction, 10 more }

Unified payload for message webhooks when using webhook_version: "2026-02-03".

This schema is used for message.sent, message.received, message.delivered, and message.read events when the subscription URL includes ?version=2026-02-03.

Key differences from V1 (2025-01-01):

  • direction: “inbound” or “outbound” instead of is_from_me boolean
  • sender_handle: Full handle object for the sender
  • chat: Nested object with id, is_group, and owner_handle
  • Message fields (id, parts, etc.) are at the top level, not nested in message

Timestamps indicate the message state:

  • message.sent: sent_at set, delivered_at=null, read_at=null
  • message.received: sent_at set, delivered_at=null, read_at=null
  • message.delivered: sent_at set, delivered_at set, read_at=null
  • message.read: sent_at set, delivered_at set, read_at set
id: string

Message identifier

formatuuid
chat: object { id, health_status, is_group, owner_handle }

Chat information

id: string

Chat identifier

formatuuid
health_status: object { doc_url, status, updated_at }

[BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.

Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.

See the Chat Health guide for what each status means and how to react.

doc_url: string

Deep-link to the relevant section of the Chat Health guide for this status.

formaturi
status: "HEALTHY" or "AT_RISK" or "CRITICAL" or "OPTED_OUT"

Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.

OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT. The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back in immediately — a reply in any conversation with you counts, the same way the block does.

OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status. Group threads are never marked and are never blocked.

Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code 2024) before the message is queued, across every chat and every line on your account. Nothing is delivered, including a final courtesy message — to send one, set override_optout: true on that single request.

One of the following:
"HEALTHY"
"AT_RISK"
"CRITICAL"
"OPTED_OUT"
updated_at: string

When this status last changed.

formatdate-time
is_group: optional boolean

Whether this is a group chat

owner_handle: optional ChatHandle { id, handle, joined_at, 4 more }

Your phone number’s handle. Always has is_me=true.

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
direction: "inbound" or "outbound"

Message direction - “outbound” if sent by you, “inbound” if received

One of the following:
"inbound"
"outbound"
parts: array of SchemasTextPartResponse { type, value } or SchemasMediaPartResponse { id, filename, mime_type, 3 more } or object { type, value }

Message parts (text and/or media)

One of the following:
SchemasTextPartResponse object { type, value }

A text message part

type: "text"

Indicates this is a text message part

value: string

The text content

SchemasMediaPartResponse object { id, filename, mime_type, 3 more }

A media attachment part

id: string

Unique attachment identifier

formatuuid
filename: string

Original filename

mime_type: string

MIME type of the file

size_bytes: number

File size in bytes

type: "media"

Indicates this is a media attachment part

url: string

Presigned URL for downloading the attachment (expires in 1 hour).

formaturi
Link object { type, value }

A rich link preview part

type: "link"

Indicates this is a rich link preview part

value: string

The URL

sender_handle: ChatHandle { id, handle, joined_at, 4 more }

The handle that sent this message

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
delivered_at: optional string

When the message was delivered. Null if not yet delivered.

formatdate-time
idempotency_key: optional string

Idempotency key for deduplication of outbound messages.

read_at: optional string

When the message was read. Null if not yet read.

formatdate-time
reconciled_at: optional string

Present only when this message was recovered by reconciliation rather than delivered live, and set to the time of that recovery. The field is omitted entirely for normally-delivered messages, which is the overwhelming majority. When present, expect sent_at to be substantially earlier than delivery of this event: the message is genuine but is arriving late and out of real-time order, so treat it as history rather than as a live inbound (for example, suppress auto-replies).

formatdate-time
reply_to: optional object { message_id, part_index }

Reference to the message this is replying to (for threaded replies)

message_id: optional string

ID of the message being replied to

formatuuid
part_index: optional number

Index of the part being replied to

formatint32
minimum0
sent_at: optional string

When the message was sent. Null if not yet sent.

formatdate-time
zero_retention: optional boolean

True when this message was sent on a zero-day-retention line. parts is always empty in that case — Linq never persists this message’s content, so there is nothing to include here, not even a count or type of what was sent.

event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

MessageReceivedWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for message.received events (2026-02-03 format)

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: MessageEventV2 { id, chat, direction, 10 more }

Unified payload for message webhooks when using webhook_version: "2026-02-03".

This schema is used for message.sent, message.received, message.delivered, and message.read events when the subscription URL includes ?version=2026-02-03.

Key differences from V1 (2025-01-01):

  • direction: “inbound” or “outbound” instead of is_from_me boolean
  • sender_handle: Full handle object for the sender
  • chat: Nested object with id, is_group, and owner_handle
  • Message fields (id, parts, etc.) are at the top level, not nested in message

Timestamps indicate the message state:

  • message.sent: sent_at set, delivered_at=null, read_at=null
  • message.received: sent_at set, delivered_at=null, read_at=null
  • message.delivered: sent_at set, delivered_at set, read_at=null
  • message.read: sent_at set, delivered_at set, read_at set
id: string

Message identifier

formatuuid
chat: object { id, health_status, is_group, owner_handle }

Chat information

id: string

Chat identifier

formatuuid
health_status: object { doc_url, status, updated_at }

[BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.

Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.

See the Chat Health guide for what each status means and how to react.

doc_url: string

Deep-link to the relevant section of the Chat Health guide for this status.

formaturi
status: "HEALTHY" or "AT_RISK" or "CRITICAL" or "OPTED_OUT"

Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.

OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT. The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back in immediately — a reply in any conversation with you counts, the same way the block does.

OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status. Group threads are never marked and are never blocked.

Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code 2024) before the message is queued, across every chat and every line on your account. Nothing is delivered, including a final courtesy message — to send one, set override_optout: true on that single request.

One of the following:
"HEALTHY"
"AT_RISK"
"CRITICAL"
"OPTED_OUT"
updated_at: string

When this status last changed.

formatdate-time
is_group: optional boolean

Whether this is a group chat

owner_handle: optional ChatHandle { id, handle, joined_at, 4 more }

Your phone number’s handle. Always has is_me=true.

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
direction: "inbound" or "outbound"

Message direction - “outbound” if sent by you, “inbound” if received

One of the following:
"inbound"
"outbound"
parts: array of SchemasTextPartResponse { type, value } or SchemasMediaPartResponse { id, filename, mime_type, 3 more } or object { type, value }

Message parts (text and/or media)

One of the following:
SchemasTextPartResponse object { type, value }

A text message part

type: "text"

Indicates this is a text message part

value: string

The text content

SchemasMediaPartResponse object { id, filename, mime_type, 3 more }

A media attachment part

id: string

Unique attachment identifier

formatuuid
filename: string

Original filename

mime_type: string

MIME type of the file

size_bytes: number

File size in bytes

type: "media"

Indicates this is a media attachment part

url: string

Presigned URL for downloading the attachment (expires in 1 hour).

formaturi
Link object { type, value }

A rich link preview part

type: "link"

Indicates this is a rich link preview part

value: string

The URL

sender_handle: ChatHandle { id, handle, joined_at, 4 more }

The handle that sent this message

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
delivered_at: optional string

When the message was delivered. Null if not yet delivered.

formatdate-time
idempotency_key: optional string

Idempotency key for deduplication of outbound messages.

read_at: optional string

When the message was read. Null if not yet read.

formatdate-time
reconciled_at: optional string

Present only when this message was recovered by reconciliation rather than delivered live, and set to the time of that recovery. The field is omitted entirely for normally-delivered messages, which is the overwhelming majority. When present, expect sent_at to be substantially earlier than delivery of this event: the message is genuine but is arriving late and out of real-time order, so treat it as history rather than as a live inbound (for example, suppress auto-replies).

formatdate-time
reply_to: optional object { message_id, part_index }

Reference to the message this is replying to (for threaded replies)

message_id: optional string

ID of the message being replied to

formatuuid
part_index: optional number

Index of the part being replied to

formatint32
minimum0
sent_at: optional string

When the message was sent. Null if not yet sent.

formatdate-time
zero_retention: optional boolean

True when this message was sent on a zero-day-retention line. parts is always empty in that case — Linq never persists this message’s content, so there is nothing to include here, not even a count or type of what was sent.

event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

MessageReadWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for message.read events (2026-02-03 format)

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: MessageEventV2 { id, chat, direction, 10 more }

Unified payload for message webhooks when using webhook_version: "2026-02-03".

This schema is used for message.sent, message.received, message.delivered, and message.read events when the subscription URL includes ?version=2026-02-03.

Key differences from V1 (2025-01-01):

  • direction: “inbound” or “outbound” instead of is_from_me boolean
  • sender_handle: Full handle object for the sender
  • chat: Nested object with id, is_group, and owner_handle
  • Message fields (id, parts, etc.) are at the top level, not nested in message

Timestamps indicate the message state:

  • message.sent: sent_at set, delivered_at=null, read_at=null
  • message.received: sent_at set, delivered_at=null, read_at=null
  • message.delivered: sent_at set, delivered_at set, read_at=null
  • message.read: sent_at set, delivered_at set, read_at set
id: string

Message identifier

formatuuid
chat: object { id, health_status, is_group, owner_handle }

Chat information

id: string

Chat identifier

formatuuid
health_status: object { doc_url, status, updated_at }

[BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.

Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.

See the Chat Health guide for what each status means and how to react.

doc_url: string

Deep-link to the relevant section of the Chat Health guide for this status.

formaturi
status: "HEALTHY" or "AT_RISK" or "CRITICAL" or "OPTED_OUT"

Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.

OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT. The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back in immediately — a reply in any conversation with you counts, the same way the block does.

OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status. Group threads are never marked and are never blocked.

Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code 2024) before the message is queued, across every chat and every line on your account. Nothing is delivered, including a final courtesy message — to send one, set override_optout: true on that single request.

One of the following:
"HEALTHY"
"AT_RISK"
"CRITICAL"
"OPTED_OUT"
updated_at: string

When this status last changed.

formatdate-time
is_group: optional boolean

Whether this is a group chat

owner_handle: optional ChatHandle { id, handle, joined_at, 4 more }

Your phone number’s handle. Always has is_me=true.

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
direction: "inbound" or "outbound"

Message direction - “outbound” if sent by you, “inbound” if received

One of the following:
"inbound"
"outbound"
parts: array of SchemasTextPartResponse { type, value } or SchemasMediaPartResponse { id, filename, mime_type, 3 more } or object { type, value }

Message parts (text and/or media)

One of the following:
SchemasTextPartResponse object { type, value }

A text message part

type: "text"

Indicates this is a text message part

value: string

The text content

SchemasMediaPartResponse object { id, filename, mime_type, 3 more }

A media attachment part

id: string

Unique attachment identifier

formatuuid
filename: string

Original filename

mime_type: string

MIME type of the file

size_bytes: number

File size in bytes

type: "media"

Indicates this is a media attachment part

url: string

Presigned URL for downloading the attachment (expires in 1 hour).

formaturi
Link object { type, value }

A rich link preview part

type: "link"

Indicates this is a rich link preview part

value: string

The URL

sender_handle: ChatHandle { id, handle, joined_at, 4 more }

The handle that sent this message

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
delivered_at: optional string

When the message was delivered. Null if not yet delivered.

formatdate-time
idempotency_key: optional string

Idempotency key for deduplication of outbound messages.

read_at: optional string

When the message was read. Null if not yet read.

formatdate-time
reconciled_at: optional string

Present only when this message was recovered by reconciliation rather than delivered live, and set to the time of that recovery. The field is omitted entirely for normally-delivered messages, which is the overwhelming majority. When present, expect sent_at to be substantially earlier than delivery of this event: the message is genuine but is arriving late and out of real-time order, so treat it as history rather than as a live inbound (for example, suppress auto-replies).

formatdate-time
reply_to: optional object { message_id, part_index }

Reference to the message this is replying to (for threaded replies)

message_id: optional string

ID of the message being replied to

formatuuid
part_index: optional number

Index of the part being replied to

formatint32
minimum0
sent_at: optional string

When the message was sent. Null if not yet sent.

formatdate-time
zero_retention: optional boolean

True when this message was sent on a zero-day-retention line. parts is always empty in that case — Linq never persists this message’s content, so there is nothing to include here, not even a count or type of what was sent.

event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

MessageDeliveredWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for message.delivered events (2026-02-03 format)

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: MessageEventV2 { id, chat, direction, 10 more }

Unified payload for message webhooks when using webhook_version: "2026-02-03".

This schema is used for message.sent, message.received, message.delivered, and message.read events when the subscription URL includes ?version=2026-02-03.

Key differences from V1 (2025-01-01):

  • direction: “inbound” or “outbound” instead of is_from_me boolean
  • sender_handle: Full handle object for the sender
  • chat: Nested object with id, is_group, and owner_handle
  • Message fields (id, parts, etc.) are at the top level, not nested in message

Timestamps indicate the message state:

  • message.sent: sent_at set, delivered_at=null, read_at=null
  • message.received: sent_at set, delivered_at=null, read_at=null
  • message.delivered: sent_at set, delivered_at set, read_at=null
  • message.read: sent_at set, delivered_at set, read_at set
id: string

Message identifier

formatuuid
chat: object { id, health_status, is_group, owner_handle }

Chat information

id: string

Chat identifier

formatuuid
health_status: object { doc_url, status, updated_at }

[BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.

Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.

See the Chat Health guide for what each status means and how to react.

doc_url: string

Deep-link to the relevant section of the Chat Health guide for this status.

formaturi
status: "HEALTHY" or "AT_RISK" or "CRITICAL" or "OPTED_OUT"

Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.

OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT. The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back in immediately — a reply in any conversation with you counts, the same way the block does.

OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status. Group threads are never marked and are never blocked.

Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code 2024) before the message is queued, across every chat and every line on your account. Nothing is delivered, including a final courtesy message — to send one, set override_optout: true on that single request.

One of the following:
"HEALTHY"
"AT_RISK"
"CRITICAL"
"OPTED_OUT"
updated_at: string

When this status last changed.

formatdate-time
is_group: optional boolean

Whether this is a group chat

owner_handle: optional ChatHandle { id, handle, joined_at, 4 more }

Your phone number’s handle. Always has is_me=true.

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
direction: "inbound" or "outbound"

Message direction - “outbound” if sent by you, “inbound” if received

One of the following:
"inbound"
"outbound"
parts: array of SchemasTextPartResponse { type, value } or SchemasMediaPartResponse { id, filename, mime_type, 3 more } or object { type, value }

Message parts (text and/or media)

One of the following:
SchemasTextPartResponse object { type, value }

A text message part

type: "text"

Indicates this is a text message part

value: string

The text content

SchemasMediaPartResponse object { id, filename, mime_type, 3 more }

A media attachment part

id: string

Unique attachment identifier

formatuuid
filename: string

Original filename

mime_type: string

MIME type of the file

size_bytes: number

File size in bytes

type: "media"

Indicates this is a media attachment part

url: string

Presigned URL for downloading the attachment (expires in 1 hour).

formaturi
Link object { type, value }

A rich link preview part

type: "link"

Indicates this is a rich link preview part

value: string

The URL

sender_handle: ChatHandle { id, handle, joined_at, 4 more }

The handle that sent this message

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
delivered_at: optional string

When the message was delivered. Null if not yet delivered.

formatdate-time
idempotency_key: optional string

Idempotency key for deduplication of outbound messages.

read_at: optional string

When the message was read. Null if not yet read.

formatdate-time
reconciled_at: optional string

Present only when this message was recovered by reconciliation rather than delivered live, and set to the time of that recovery. The field is omitted entirely for normally-delivered messages, which is the overwhelming majority. When present, expect sent_at to be substantially earlier than delivery of this event: the message is genuine but is arriving late and out of real-time order, so treat it as history rather than as a live inbound (for example, suppress auto-replies).

formatdate-time
reply_to: optional object { message_id, part_index }

Reference to the message this is replying to (for threaded replies)

message_id: optional string

ID of the message being replied to

formatuuid
part_index: optional number

Index of the part being replied to

formatint32
minimum0
sent_at: optional string

When the message was sent. Null if not yet sent.

formatdate-time
zero_retention: optional boolean

True when this message was sent on a zero-day-retention line. parts is always empty in that case — Linq never persists this message’s content, so there is nothing to include here, not even a count or type of what was sent.

event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

MessageFailedWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for message.failed events

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: object { code, failed_at, chat_id, 4 more }

Error details for message.failed webhook events. See WebhookErrorCode for the full error code reference.

In rare cases the message can still be delivered after this event fires — a message.delivered webhook for the same message ID may follow.

code: number

Error codes in webhook failure events. The possible set varies by event: message.failed and poll.failed can carry 3007, 4001, 4002, 4005, 4006, 4007, or 4008; the group update failure events (chat.group_name_update_failed, chat.group_icon_update_failed) carry 3007 or 4001; chat.background_update_failed carries 1005, 2011, 4001, or 5002.

failed_at: string

When the failure was detected

formatdate-time
chat_id: optional string

Chat identifier (UUID)

detail_code: optional number

Opaque diagnostic code identifying the specific failure class within code. Values are not enumerated and may change without notice — log it and include it in support requests, but do not branch on it.

message_id: optional string

Message identifier (UUID)

reason: optional string

Human-readable description of the failure

service: optional ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

ReactionAddedWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for reaction.added events

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: ReactionEventBase { is_from_me, reaction_type, chat_id, 8 more }

Payload for reaction.added webhook events

is_from_me: boolean

Whether this reaction was from the owner of the phone number (true) or from someone else (false)

reaction_type: ReactionType

Type of reaction. Standard reactions are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type “custom” with the actual emoji in the custom_emoji field.

One of the following:
"love"
"like"
"dislike"
"laugh"
"emphasize"
"question"
"custom"
chat_id: optional string

Chat identifier (UUID)

custom_emoji: optional string

The actual emoji when reaction_type is “custom”. Null for standard reactions.

Deprecatedfrom: optional string

DEPRECATED: Use from_handle instead. Phone number or email address of the person who added/removed the reaction.

from_handle: optional ChatHandle { id, handle, joined_at, 4 more }

The person who added/removed the reaction as a full handle object

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
message_id: optional string

Message identifier (UUID) that the reaction was added to or removed from

part_index: optional number

Index of the message part that was reacted to (0-based)

formatint32
minimum0
reacted_at: optional string

When the reaction was added or removed

formatdate-time
reaction_id: optional string

Identifier for this reaction.

formatuuid
service: optional ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

ReactionRemovedWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for reaction.removed events

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: ReactionEventBase { is_from_me, reaction_type, chat_id, 8 more }

Payload for reaction.removed webhook events

is_from_me: boolean

Whether this reaction was from the owner of the phone number (true) or from someone else (false)

reaction_type: ReactionType

Type of reaction. Standard reactions are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type “custom” with the actual emoji in the custom_emoji field.

One of the following:
"love"
"like"
"dislike"
"laugh"
"emphasize"
"question"
"custom"
chat_id: optional string

Chat identifier (UUID)

custom_emoji: optional string

The actual emoji when reaction_type is “custom”. Null for standard reactions.

Deprecatedfrom: optional string

DEPRECATED: Use from_handle instead. Phone number or email address of the person who added/removed the reaction.

from_handle: optional ChatHandle { id, handle, joined_at, 4 more }

The person who added/removed the reaction as a full handle object

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
message_id: optional string

Message identifier (UUID) that the reaction was added to or removed from

part_index: optional number

Index of the message part that was reacted to (0-based)

formatint32
minimum0
reacted_at: optional string

When the reaction was added or removed

formatdate-time
reaction_id: optional string

Identifier for this reaction.

formatuuid
service: optional ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

ParticipantAddedWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for participant.added events

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: object { handle, added_at, chat_id, participant }

Payload for participant.added webhook events

Deprecatedhandle: string

DEPRECATED: Use participant instead. Handle (phone number or email address) of the added participant.

added_at: optional string

When the participant was added

formatdate-time
chat_id: optional string

Chat identifier (UUID) of the group chat

participant: optional ChatHandle { id, handle, joined_at, 4 more }

The added participant as a full handle object

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

ParticipantRemovedWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for participant.removed events

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: object { handle, chat_id, participant, removed_at }

Payload for participant.removed webhook events

Deprecatedhandle: string

DEPRECATED: Use participant instead. Handle (phone number or email address) of the removed participant.

chat_id: optional string

Chat identifier (UUID) of the group chat

participant: optional ChatHandle { id, handle, joined_at, 4 more }

The removed participant as a full handle object

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
removed_at: optional string

When the participant was removed

formatdate-time
event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

ChatCreatedWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for chat.created events

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: object { id, created_at, display_name, 5 more }

Payload for chat.created webhook events. Matches GET /v3/chats/{chatId} response.

id: string

Unique identifier for the chat

formatuuid
created_at: string

When the chat was created

formatdate-time
display_name: string

Display name for the chat. Defaults to a comma-separated list of recipient handles. Can be updated for group chats.

handles: array of ChatHandle { id, handle, joined_at, 4 more }

List of chat participants with full handle details. Always contains at least two handles (your phone number and the other participant).

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
health_status: object { doc_url, status, updated_at }

[BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.

Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.

See the Chat Health guide for what each status means and how to react.

doc_url: string

Deep-link to the relevant section of the Chat Health guide for this status.

formaturi
status: "HEALTHY" or "AT_RISK" or "CRITICAL" or "OPTED_OUT"

Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.

OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT. The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back in immediately — a reply in any conversation with you counts, the same way the block does.

OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status. Group threads are never marked and are never blocked.

Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code 2024) before the message is queued, across every chat and every line on your account. Nothing is delivered, including a final courtesy message — to send one, set override_optout: true on that single request.

One of the following:
"HEALTHY"
"AT_RISK"
"CRITICAL"
"OPTED_OUT"
updated_at: string

When this status last changed.

formatdate-time
is_group: boolean

Whether this is a group chat

updated_at: string

When the chat was last updated

formatdate-time
service: optional ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

ChatTypingIndicatorStartedWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for chat.typing_indicator.started events

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: object { chat_id, actor_handle }

Payload for chat.typing_indicator.started webhook events

chat_id: string

Chat identifier

formatuuid
actor_handle: optional ChatHandle { id, handle, joined_at, 4 more }

Who is typing.

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.

ChatTypingIndicatorStoppedWebhookEvent object { api_version, created_at, data, 5 more }

Complete webhook payload for chat.typing_indicator.stopped events

api_version: string

API version for the webhook payload format

created_at: string

When the event was created

formatdate-time
data: object { chat_id, actor_handle }

Payload for chat.typing_indicator.stopped webhook events

chat_id: string

Chat identifier

formatuuid
actor_handle: optional ChatHandle { id, handle, joined_at, 4 more }

Who stopped typing.

id: string

Unique identifier for this handle

formatuuid
handle: string

Phone number (E.164) or email address of the participant

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type. Where this names the transport a message used, it is per-message: a chat’s own service can differ from a message in it, and a conversation can fall back from RCS to SMS.

One of the following:
"SMS"
"RCS"
is_me: optional boolean

Whether this handle belongs to the sender (your phone number)

left_at: optional string

When they left (if applicable)

formatdate-time
status: optional "active" or "left" or "removed"

Participant status

One of the following:
"active"
"left"
"removed"
event_id: string

Unique identifier for this event (for deduplication)

formatuuid
event_type: WebhookEventType

Valid webhook event types that can be subscribed to.

Note: message.edited is only delivered to subscriptions using webhook_version: "2026-02-03". Subscribing to this event on a v2025 subscription will not produce any deliveries.

One of the following:
"message.sent"
"message.received"
"message.read"
"message.delivered"
"message.failed"
"message.edited"
"reaction.added"
"reaction.removed"
"poll.received"
"poll.failed"
"poll.sent"
"poll.delivered"
"poll.read"
"poll.updated"
"poll.vote.added"
"poll.vote.removed"
"poll.reaction.added"
"participant.added"
"participant.removed"
"chat.created"
"chat.group_name_updated"
"chat.group_icon_updated"
"chat.group_name_update_failed"
"chat.group_icon_update_failed"
"chat.background_updated"
"chat.background_update_failed"
"chat.typing_indicator.started"
"chat.typing_indicator.stopped"
"phone_number.status_updated"
"phone_number.assigned"
"phone_number.released"
"contact_card.received"
"call.initiated"
"call.ringing"
"call.answered"
"call.ended"
"call.failed"
"call.declined"
"call.no_answer"
"location.sharing.started"
"location.sharing.stopped"
"payment.succeeded"
"payment.canceled"
"payment.expired"
"payment.declined"
"payment.authorized"
"connection.created"
"connection.revoked"
"zero_day_retention.updated"
"phone_number.forwarding_updated"
"environment.line_moved"
"contact_card.created"
"contact_card.updated"
"contact_card.deleted"
"api_token.created"
"api_token.renamed"
"api_token.expiry_scheduled"
"api_token.expired"
"api_token.activated"
"api_token.deleted"
"environment.created"
"environment.renamed"
"environment.deleted"
"webhook_subscription.created"
"webhook_subscription.deleted"
"webhook_subscription.target_url_changed"
"webhook_subscription.enabled"
"webhook_subscription.disabled"
"webhook_subscription.events.updated"
"webhook_subscription.phone_numbers.updated"
"webhook_subscription.routing_headers_set"
"webhook_subscription.routing_headers_cleared"
"team_member.added"
"team_member.signed_in"
"team_member.signed_out"
partner_id: string

Partner identifier. Present on all webhooks for cross-referencing.

trace_id: string

Trace ID for debugging and correlation across systems.

webhook_version: string

Date-based webhook payload version. Determined by the ?version= query parameter in your webhook subscription URL. If no version parameter is specified, defaults based on subscription creation date.