Skip to content
Linq Copy agent prompt

Webhook Events

Event types you can subscribe to, with a representative payload for each category.

Every webhook delivered by Linq shares a common envelope with a data field specific to the event type. This page lists the event types you can subscribe to and shows a representative payload per category. Each example is sourced directly from the OpenAPI spec — pick a version tab on any example and every other example on the page switches to that version too. For setup, signature verification, and delivery guarantees see Webhooks; for subscription management see Webhook Subscriptions.

Authoritative list of event types (rendered from the OpenAPI spec): 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 .

Categories below describe the most common events. If a type appears in this canonical list but not in a category section, treat the canonical list as source of truth and refer to the API Reference: Webhook Events for the payload schema.

All webhook payloads share a common envelope:

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "message.received",
"event_id": "2915e81c-5068-4796-ace2-21d2c94ad298",
"created_at": "2026-02-05T19:31:13.736Z",
"trace_id": "8af9171a45022df2eb74ba4e4c83be0f",
"partner_id": "your-partner-id",
"data": { ... }
}
Field Description
api_version API version (v3)
webhook_version Payload version (2025-01-01 or 2026-02-03)
event_type Event type string
event_id Unique event ID (use for deduplication)
created_at When the event was created
trace_id Trace ID for debugging
partner_id Your partner identifier
data Event-specific payload
Event Description
message.sent Message successfully sent from your phone number
message.received Incoming message received on your phone number
message.delivered Message delivered to recipient’s device
message.read Message read by recipient
message.failed Message delivery failed
message.edited Message was edited (2026-02-03 version only) — see Editing messages

Lifecycle timestamps indicate the event stage:

  • sent_at — set on message.sent and message.received
  • delivered_at — set on message.delivered
  • read_at — set on message.read

message.edited is only delivered to 2026-02-03 subscriptions.

There is no mention event. Mentions come back as mentions on the text part — of message.sent, message.delivered, and message.read for one you sent, and of message.received when a participant mentions your line. The older mention / mention_range fields report only the first mention on a part and are deprecated on responses.

In 2026-02-03 payloads, the chat sub-object includes a health_status field — see Chat Health.

Note: SMS and MMS sends do not produce message.delivered or message.read webhooks — neither receipt type exists on those protocols. You’ll still get message.sent (accepted for delivery) and message.failed (hard failure), but treat the absence of a delivered event on an SMS fallback as normal, not a bug. See Protocol capabilities for the full matrix.

Outbound message confirmed as sent from your phone number. delivered_at and read_at are still null.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "message.sent",
"event_id": "e20feb41-7f67-43f0-89c8-a985cff3b568",
"created_at": "2026-02-05T19:52:18.101373886Z",
"trace_id": "2eff5df5c6f688733c007523c4d61cd9",
"partner_id": "your-partner-id",
"data": {
"chat": {
"id": "0c961e93-e7bf-4db2-bf7b-ea06826bcab4",
"is_group": false,
"owner_handle": {
"handle": "+12025551234",
"id": "8d79532a-f529-4244-a5cf-d443de051434",
"is_me": true,
"joined_at": "2026-01-21T21:59:45.191571Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"health_status": {
"status": "HEALTHY",
"doc_url": "https://docs.linqapp.com/channel/imessage/guides/chats/chat-health#healthy",
"updated_at": "2026-02-05T19:52:17.000Z"
}
},
"id": "347d62c2-2170-4754-8d30-c76d0c727d96",
"idempotency_key": null,
"direction": "outbound",
"sender_handle": {
"handle": "+12025551234",
"id": "8d79532a-f529-4244-a5cf-d443de051434",
"is_me": true,
"joined_at": "2026-01-21T21:59:45.191571Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"parts": [
{
"type": "text",
"value": "Hello from Linq!"
},
{
"filename": "photo.jpg",
"id": "f13dda7d-ecac-49eb-b3fe-16fe286abf19",
"mime_type": "image/jpeg",
"size_bytes": 245678,
"type": "media",
"url": "https://cdn.linqapp.com/attachments/a1b2c3d4/photo.jpg?signature=..."
}
],
"effect": null,
"sent_at": "2026-02-05T19:52:17.219Z",
"delivered_at": null,
"read_at": null,
"service": "iMessage",
"preferred_service": null
}
}

Inbound message from a participant. Contains the full message content and any attachments.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "message.received",
"event_id": "2915e81c-5068-4796-ace2-21d2c94ad298",
"created_at": "2026-02-05T19:31:13.736444093Z",
"trace_id": "8af9171a45022df2eb74ba4e4c83be0f",
"partner_id": "your-partner-id",
"data": {
"chat": {
"id": "8f392755-6865-4b18-880a-227f9d8b458f",
"is_group": false,
"owner_handle": {
"handle": "+12025551234",
"id": "6d6c617f-187a-4dcd-a0d5-988347a8c092",
"is_me": true,
"joined_at": "2026-01-04T05:48:51.321469Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"health_status": {
"status": "HEALTHY",
"doc_url": "https://docs.linqapp.com/channel/imessage/guides/chats/chat-health#healthy",
"updated_at": "2026-02-05T19:31:12.000Z"
}
},
"id": "89e3566e-1d13-49e5-a8ee-48490d5bfeb7",
"direction": "inbound",
"sender_handle": {
"handle": "+12025559876",
"id": "e604375a-5913-483a-8278-c631e8f0ffda",
"is_me": false,
"joined_at": "2026-01-04T05:48:51.321469Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"parts": [
{
"type": "text",
"value": "Hello!"
}
],
"effect": null,
"reply_to": null,
"sent_at": "2026-02-05T19:31:13.074Z",
"delivered_at": null,
"read_at": null,
"service": "iMessage"
}
}

Outbound message reached the recipient’s device. Fires on iMessage and RCS — not on SMS/MMS, which have no delivery receipt mechanism.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "message.delivered",
"event_id": "67c4ad39-e9b0-47f6-82f8-64bdd8ceafa6",
"created_at": "2026-02-05T19:52:22.593689073Z",
"trace_id": "abde7f6248fba00f97e8c7dc4782d7e0",
"partner_id": "your-partner-id",
"data": {
"chat": {
"id": "0c961e93-e7bf-4db2-bf7b-ea06826bcab4",
"is_group": false,
"owner_handle": {
"handle": "+12025551234",
"id": "8d79532a-f529-4244-a5cf-d443de051434",
"is_me": true,
"joined_at": "2026-01-21T21:59:45.191571Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"health_status": {
"status": "HEALTHY",
"doc_url": "https://docs.linqapp.com/channel/imessage/guides/chats/chat-health#healthy",
"updated_at": "2026-02-05T19:52:17.000Z"
}
},
"id": "347d62c2-2170-4754-8d30-c76d0c727d96",
"idempotency_key": null,
"direction": "outbound",
"sender_handle": {
"handle": "+12025551234",
"id": "8d79532a-f529-4244-a5cf-d443de051434",
"is_me": true,
"joined_at": "2026-01-21T21:59:45.191571Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"parts": [
{
"type": "text",
"value": "Hello from Linq!"
},
{
"filename": "photo.gif",
"id": "f13dda7d-ecac-49eb-b3fe-16fe286abf19",
"mime_type": "image/gif",
"size_bytes": 2776819,
"type": "media",
"url": "https://cdn.linqapp.com/attachments/f13dda7d/photo.gif?signature=..."
}
],
"effect": null,
"sent_at": "2026-02-05T19:52:17.219Z",
"delivered_at": "2026-02-05T19:52:22.291Z",
"read_at": null,
"service": "iMessage",
"preferred_service": null
}
}

Outbound message was read by the recipient. Fires on iMessage and RCS (not SMS/MMS), and requires the recipient to have read receipts enabled on their device.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "message.read",
"event_id": "8fd42065-b998-482a-93b3-da855f8dad17",
"created_at": "2026-02-05T19:13:58.833366566Z",
"trace_id": "cbb93c08fa1a3f3c4c2efc161d67f36d",
"partner_id": "your-partner-id",
"data": {
"chat": {
"id": "24e33345-e6cf-4f50-9d35-1d7fde8c9818",
"is_group": false,
"owner_handle": {
"handle": "+12025551234",
"id": "d31678e9-0442-48fd-b7ed-c898d245dd15",
"is_me": true,
"joined_at": "2026-01-18T03:38:41.442254Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"health_status": {
"status": "HEALTHY",
"doc_url": "https://docs.linqapp.com/channel/imessage/guides/chats/chat-health#healthy",
"updated_at": "2026-02-05T19:13:57.000Z"
}
},
"id": "dc6d3f68-90df-48f0-a504-e65f239a383c",
"idempotency_key": null,
"direction": "outbound",
"sender_handle": {
"handle": "+12025551234",
"id": "d31678e9-0442-48fd-b7ed-c898d245dd15",
"is_me": true,
"joined_at": "2026-01-18T03:38:41.442254Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"parts": [
{
"type": "text",
"value": "Hello world!"
}
],
"effect": null,
"sent_at": "2026-02-05T19:13:57.814Z",
"delivered_at": "2026-02-05T19:13:57.948Z",
"read_at": "2026-02-05T19:13:58.177Z",
"service": "iMessage",
"preferred_service": null
}
}

Message delivery failed. code maps to an error code; common causes are request timeouts, upstream processing errors, and service unavailability.

service is the transport on which the failure occurred (iMessage, RCS, or SMS). It is null when the message failed before a transport was established. preferred_service is the service requested for the send (iMessage, RCS, SMS, or auto). It is null when no preference was specified, which is the common case.

detail_code, when present, is an opaque diagnostic code identifying the specific failure class within code. Log it and include it in support requests, but do not branch application behavior on it; its values are not part of the stable error-code contract. Use code for programmatic error handling.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "message.failed",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"code": 4006,
"detail_code": 100001,
"reason": "Message send timed out",
"service": null,
"preferred_service": "RCS",
"failed_at": "2025-11-23T17:35:00.000Z"
}
}

A text part of a previously sent message was edited. Only delivered to subscriptions on webhook_version: "2026-02-03" — see Editing messages.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "message.edited",
"event_id": "c3d4e5f6-a7b8-9012-cdef-345678901234",
"created_at": "2026-03-05T02:12:46.501Z",
"trace_id": "d1e2f3a4b5c6d7e8f9a0b1c2d3e4f5a6",
"partner_id": "your-partner-id",
"data": {
"chat": {
"id": "8f392755-6865-4b18-880a-227f9d8b458f",
"is_group": false,
"owner_handle": {
"handle": "+12025551234",
"id": "6d6c617f-187a-4dcd-a0d5-988347a8c092",
"is_me": true,
"joined_at": "2026-01-04T05:48:51.321469Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"health_status": {
"status": "HEALTHY",
"doc_url": "https://docs.linqapp.com/channel/imessage/guides/chats/chat-health#healthy",
"updated_at": "2026-03-05T02:12:45.000Z"
}
},
"id": "89e3566e-1d13-49e5-a8ee-48490d5bfeb7",
"direction": "outbound",
"sender_handle": {
"handle": "+12025551234",
"id": "6d6c617f-187a-4dcd-a0d5-988347a8c092",
"is_me": true,
"joined_at": "2026-01-04T05:48:51.321469Z",
"left_at": null,
"service": "iMessage",
"status": "active"
},
"part": {
"index": 0,
"text": "This is the edited message content"
},
"edited_at": "2026-03-05T02:12:46.487Z"
}
}
Event Description
reaction.added Reaction (tapback) added to a message — see Reactions
reaction.removed Reaction removed from a message — see Reactions

Both events share the ReactionEventBase shape and are identical across versions. The reaction_type field indicates the kind of reaction:

  • Tapback — one of love, like, dislike, laugh, emphasize, question
  • Custom emoji — reaction_type: "custom", emoji in custom_emoji
  • Sticker — reaction_type: "sticker", details in a sticker object — see Stickers

A standard tapback (love) added to a message part.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "reaction.added",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"part_index": 0,
"reaction_type": "love",
"custom_emoji": null,
"is_from_me": false,
"from": "+14155559876",
"from_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2025-11-23T17:30:00.000Z",
"left_at": null
},
"service": "iMessage",
"reacted_at": "2025-11-23T17:35:00.000Z",
"sticker": null
}
}

Same shape as reaction.added — reacted_at is when the reaction was taken off.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "reaction.removed",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"part_index": 0,
"reaction_type": "love",
"custom_emoji": null,
"is_from_me": false,
"from": "+14155559876",
"from_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2025-11-23T17:30:00.000Z",
"left_at": null
},
"service": "iMessage",
"reacted_at": "2025-11-23T17:35:00.000Z",
"sticker": null
}
}
Event Description
poll.received A participant sent a poll to your line — see Polls
poll.sent A poll you created left the device
poll.delivered That poll reached the recipient
poll.read The recipient read it
poll.updated Options were added to an existing poll
poll.failed An outbound poll or poll action failed to send
poll.vote.added A participant voted for an option
poll.vote.removed A participant took a vote back
poll.reaction.added Someone reacted to the poll message

Poll events are delivered to 2026-02-03 subscriptions. Throughout, message_id is the poll-definition message — the same id you pass to the poll endpoints. poll.sent, poll.delivered, and poll.read share one shape whose timestamps fill in as the poll progresses (null means not yet).

A participant sent your line a poll. Carries the full snapshot at receipt time — options present, no voters yet.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "poll.received",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-08T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"direction": "inbound",
"chat": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_group": false,
"owner_handle": {
"id": "550e8400-e29b-41d4-a716-446655440092",
"handle": "+12025551234",
"is_me": true,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T05:48:51.321Z",
"left_at": null
}
},
"sender_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T17:30:00.000Z",
"left_at": null
},
"created_at": "2026-07-08T17:35:00.000Z",
"updated_at": "2026-07-08T17:35:00.000Z",
"poll": {
"options": [
{
"option_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"text": "Tacos",
"can_be_edited": true,
"creator_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T17:30:00.000Z",
"left_at": null
},
"voters": []
},
{
"option_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3302",
"text": "Sushi",
"can_be_edited": true,
"creator_handle": null,
"voters": []
}
],
"total_voters": 0
},
"service": "iMessage",
"received_at": "2026-07-08T17:35:00.000Z"
}
}

A poll your line created left the device. delivered_at and read_at are null until the matching events fire.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "poll.sent",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-08T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"direction": "outbound",
"chat": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_group": false,
"owner_handle": null
},
"sender_handle": {
"id": "550e8400-e29b-41d4-a716-446655440092",
"handle": "+12025551234",
"is_me": true,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T05:48:51.321Z",
"left_at": null
},
"created_at": "2026-07-08T17:35:00.000Z",
"updated_at": "2026-07-08T17:35:00.000Z",
"poll": {
"options": [
{
"option_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"text": "Tacos",
"can_be_edited": true,
"creator_handle": null,
"voters": []
}
],
"total_voters": 0
},
"service": "iMessage",
"sent_at": "2026-07-08T17:35:00.000Z",
"delivered_at": null,
"read_at": null
}
}

Same shape as poll.sent, with delivered_at populated.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "poll.delivered",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-08T17:35:02.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"direction": "outbound",
"chat": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_group": false,
"owner_handle": null
},
"sender_handle": {
"id": "550e8400-e29b-41d4-a716-446655440092",
"handle": "+12025551234",
"is_me": true,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T05:48:51.321Z",
"left_at": null
},
"created_at": "2026-07-08T17:35:00.000Z",
"updated_at": "2026-07-08T17:35:02.000Z",
"poll": {
"options": [
{
"option_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"text": "Tacos",
"can_be_edited": true,
"creator_handle": null,
"voters": []
}
],
"total_voters": 0
},
"service": "iMessage",
"sent_at": "2026-07-08T17:35:00.000Z",
"delivered_at": "2026-07-08T17:35:02.000Z",
"read_at": null
}
}

The recipient read the poll. Requires read receipts on their side, and is not available in group chats.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "poll.read",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-08T17:36:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"direction": "outbound",
"chat": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_group": false,
"owner_handle": null
},
"sender_handle": {
"id": "550e8400-e29b-41d4-a716-446655440092",
"handle": "+12025551234",
"is_me": true,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T05:48:51.321Z",
"left_at": null
},
"created_at": "2026-07-08T17:35:00.000Z",
"updated_at": "2026-07-08T17:36:00.000Z",
"poll": {
"options": [
{
"option_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"text": "Tacos",
"can_be_edited": true,
"creator_handle": null,
"voters": []
}
],
"total_voters": 0
},
"service": "iMessage",
"sent_at": "2026-07-08T17:35:00.000Z",
"delivered_at": "2026-07-08T17:35:02.000Z",
"read_at": "2026-07-08T17:36:00.000Z"
}
}

Options were added. added_options carries only the new ones — fetch GET /v3/messages/{messageId}/poll for the full poll.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "poll.updated",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-08T17:40:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"direction": "inbound",
"chat": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_group": false,
"owner_handle": null
},
"sender_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T17:30:00.000Z",
"left_at": null
},
"added_options": [
{
"option_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3303",
"text": "Pizza",
"can_be_edited": true,
"creator_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T17:30:00.000Z",
"left_at": null
},
"voters": []
}
],
"service": "iMessage"
}
}

An outbound poll or poll action failed to send. sender_handle is null because the send never landed. Error codes match message.failed.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "poll.failed",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-08T17:35:05.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"direction": "outbound",
"chat": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_group": false,
"owner_handle": null
},
"sender_handle": null,
"poll": {
"options": [
{
"option_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"text": "Tacos",
"can_be_edited": true,
"creator_handle": null,
"voters": []
}
],
"total_voters": 0
},
"service": "iMessage",
"error": {
"code": 4001,
"message": "Message send failed"
},
"failed_at": "2026-07-08T17:35:05.000Z"
}
}

A participant voted for one option. Votes toggle per option, so a voter picking three options produces three events.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "poll.vote.added",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-08T17:38:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"direction": "inbound",
"chat": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_group": false,
"owner_handle": null
},
"sender_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T17:30:00.000Z",
"left_at": null
},
"option_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"service": "iMessage"
}
}

A participant took a vote back. Identical shape to poll.vote.added.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "poll.vote.removed",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-08T17:39:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"direction": "inbound",
"chat": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_group": false,
"owner_handle": null
},
"sender_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T17:30:00.000Z",
"left_at": null
},
"option_id": "3f2504e0-4f89-11d3-9a0c-0305e82c3301",
"service": "iMessage"
}
}

Someone reacted to the poll message. Same shape as reaction.added, with message_id pointing at the poll-definition message. Poll reactions are stickers, which cannot be removed, so there is no removal counterpart.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "poll.reaction.added",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-08T17:41:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"message_id": "550e8400-e29b-41d4-a716-446655440001",
"part_index": 0,
"reaction_type": "love",
"custom_emoji": null,
"is_from_me": false,
"from": "+14155559876",
"from_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T17:30:00.000Z",
"left_at": null
},
"service": "iMessage",
"reacted_at": "2026-07-08T17:41:00.000Z",
"sticker": null
}
}
Event Description
chat.created New chat created — fires for DMs and group chats
chat.group_name_updated Group chat display name changed
chat.group_icon_updated Group chat icon changed
chat.group_name_update_failed Group name update failed
chat.group_icon_update_failed Group icon update failed
chat.background_updated Chat transcript background set, changed, or removed — see Chat Backgrounds
chat.background_update_failed Background set or removal failed
chat.typing_indicator.started Participant started typing — see Typing Indicators
chat.typing_indicator.stopped Participant stopped typing — see Typing Indicators

Chat-level events use a consistent shape across versions.

The data block mirrors the GET /v3/chats/{chatId} response. In 2026-02-03 payloads, health_status is included — see Chat Health.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "chat.created",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"display_name": "+14155551234, +14155559876",
"service": "iMessage",
"handles": [
{
"id": "550e8400-e29b-41d4-a716-446655440010",
"handle": "+14155551234",
"is_me": true,
"service": "iMessage",
"status": "active",
"joined_at": "2025-11-23T17:30:00.000Z",
"left_at": null
},
{
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2025-11-23T17:30:00.000Z",
"left_at": null
}
],
"is_group": false,
"created_at": "2025-11-23T17:30:00.000Z",
"updated_at": "2025-11-23T17:30:00.000Z",
"health_status": {
"status": "HEALTHY",
"doc_url": "https://docs.linqapp.com/channel/imessage/guides/chats/chat-health#healthy",
"updated_at": "2025-11-23T17:30:00.000Z"
}
}
}

new_value is null when the name was removed; old_value is null when no previous name existed.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "chat.group_name_updated",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"old_value": "Old Group Name",
"new_value": "New Group Name",
"changed_by_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2025-11-23T17:30:00.000Z",
"left_at": null
},
"updated_at": "2025-11-23T17:50:00.000Z"
}
}

Same shape as chat.group_name_updated; old_value and new_value are image URLs (null when absent).

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "chat.group_icon_updated",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"old_value": "https://example.com/old-icon.png",
"new_value": "https://example.com/new-icon.png",
"changed_by_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2025-11-23T17:30:00.000Z",
"left_at": null
},
"updated_at": "2025-11-23T17:50:00.000Z"
}
}

Fires when a PUT /v3/chats/{chatId} request to change the display name couldn’t be applied. error_code follows the standard error code list.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "chat.group_name_update_failed",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"error_code": 3007,
"failed_at": "2025-11-23T17:55:00.000Z"
}
}

Identical shape to chat.group_name_update_failed, fired when the group icon update couldn’t be applied.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "chat.group_icon_update_failed",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"error_code": 3007,
"failed_at": "2025-11-23T17:55:00.000Z"
}
}

A chat’s transcript background was set, changed, or removed — see Chat Backgrounds. background is null on removal. actor_handle.is_me distinguishes your own change from a participant’s, so a subscription sees both directions.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "chat.background_updated",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-14T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat": {
"id": "550e8400-e29b-41d4-a716-446655440000",
"is_group": false,
"owner_handle": {
"id": "550e8400-e29b-41d4-a716-446655440092",
"handle": "+12025551234",
"is_me": true,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T05:48:51.321Z",
"left_at": null
}
},
"background": { "type": "dynamic", "style": "water", "variant": "dark" },
"actor_handle": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2026-07-01T17:30:00.000Z",
"left_at": null
}
}
}

The terminal failure counterpart of chat.background_updated, fired when setting or removing a background couldn’t be applied. error_code follows the standard error code list. An accepted request normally ends in one of the two, but a command that exhausts its internal retries emits neither — time out rather than wait indefinitely.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "chat.background_update_failed",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-07-30T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"error_code": 4001,
"failed_at": "2026-07-30T17:35:00.000Z"
}
}

Fires when a participant starts typing, in one-to-one and group chats alike — see Typing Indicators. The payload identifies the chat, not the participant, so in a group it tells you someone is typing but not who.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "chat.typing_indicator.started",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000"
}
}

Counterpart to chat.typing_indicator.started. Also fires automatically when the participant sends the message they were typing.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "chat.typing_indicator.stopped",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000"
}
}
Event Description
participant.added Participant added to a group chat
participant.removed Participant removed from a group chat

Participant events share the same shape across versions.

Fires when a new participant joins a group chat.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "participant.added",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"handle": "+14155559876",
"participant": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "active",
"joined_at": "2025-11-23T17:40:00.000Z",
"left_at": null
},
"added_at": "2025-11-23T17:40:00.000Z"
}
}

Fires when a participant leaves or is removed from a group chat. The participant object’s status is removed and left_at is set.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "participant.removed",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2025-11-23T17:35:00.000Z",
"trace_id": "abc123def456",
"partner_id": "your-partner-id",
"data": {
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"handle": "+14155559876",
"participant": {
"id": "550e8400-e29b-41d4-a716-446655440011",
"handle": "+14155559876",
"is_me": false,
"service": "iMessage",
"status": "removed",
"joined_at": "2025-11-23T17:30:00.000Z",
"left_at": "2025-11-23T17:45:00.000Z"
},
"removed_at": "2025-11-23T17:45:00.000Z"
}
}
Event Description
phone_number.status_updated Phone number status (ACTIVE ↔ FLAGGED) or reputation (HEALTHY / AT_RISK / CRITICAL) changed — see Phone Numbers and Phone Reputation

Fires when a phone number’s service status (ACTIVE ↔ FLAGGED) or reputation (HEALTHY / AT_RISK / CRITICAL) changes. Every payload carries both pairs of fields, so you can react to either signal from the same event.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "phone_number.status_updated",
"event_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
"created_at": "2026-02-18T18:35:05.363Z",
"trace_id": "b66e67c5c6b2c20e41d53c51698db27a",
"partner_id": "your-partner-id",
"data": {
"phone_number": "+12025551234",
"previous_status": "ACTIVE",
"new_status": "FLAGGED",
"previous_reputation": "AT_RISK",
"new_reputation": "CRITICAL",
"changed_at": "2026-02-18T18:35:05.000Z"
}
}
Event Description
location.sharing.started A participant started sharing their location with you — see Location Sharing
location.sharing.stopped A participant stopped sharing their location — including when you stop their share

Both payloads carry shared_by (their phone number — or Apple ID email if they shared from the standalone Find My app, see Location Sharing), shared_with (your number), began_at, and chat_id. On location.sharing.started, ends_at is always present — a timestamp when the share is time-boxed, null when the contact shares indefinitely. On location.sharing.stopped, began_at and ended_at bound the session that just ended, so its duration comes from that event alone. After a started event, call Read shared locations to pull the current coordinates. These events fire only when sharing begins or ends — there is no webhook for coordinate updates.

Fires when a participant starts sharing their location with you.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "location.sharing.started",
"event_id": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2026-02-04T12:00:00Z",
"trace_id": "2eff5df5c6f688733c007523c4d61cd9",
"partner_id": "your-partner-id",
"data": {
"shared_by": "+15551234567",
"shared_with": "+15559876543",
"began_at": "2026-02-04T12:00:00Z",
"ends_at": "2026-02-04T13:00:00Z",
"chat_id": "550e8400-e29b-41d4-a716-446655440000"
}
}

Fires when a participant stops sharing their location. It also confirms a stop you requested with the Stop Location Sharing endpoint — that call returns 202 on acceptance, and this event is what tells you sharing has actually ended. See Stop a location share.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "location.sharing.stopped",
"event_id": "660f9500-f30c-52e5-b827-557766551111",
"created_at": "2026-02-04T18:45:00Z",
"trace_id": "3bff6ef6d7g799844d118634d5e72de0",
"partner_id": "your-partner-id",
"data": {
"shared_by": "+15551234567",
"shared_with": "+15559876543",
"began_at": "2026-02-04T12:00:00Z",
"ended_at": "2026-02-04T18:45:00Z",
"chat_id": "550e8400-e29b-41d4-a716-446655440000"
}
}

Account events announce changes to your account: API tokens, environments, webhook subscriptions, contact cards, a line’s call forwarding or environment, zero-day retention, and team members. Each one is the same change shown on the Activity page in your dashboard. Subscribe to them by adding their names to subscribed_events like any other event. The payload is the same on every webhook version.

Event Description
zero_day_retention.updated Zero-day retention was turned on or off. change values are booleans.
phone_number.forwarding_updated A line’s call forwarding number changed. change values are E.164 numbers; to: null means forwarding was turned off.
environment.line_moved A line moved to another environment. change values are environments, identified by name.
contact_card.created A contact card was created for a line.
contact_card.updated A contact card’s name or photo changed. change has first_name, last_name and/or image_url, each present only when it changed.
contact_card.deleted A contact card was deleted.
api_token.created An API token was created. expires_at is null when it never expires.
api_token.renamed An API token was renamed.
api_token.expiry_scheduled An API token was set to expire at a future time. change values are timestamps; null means it never expires.
api_token.expired An API token was expired immediately.
api_token.activated An expired or expiring API token was made active again with no expiry.
api_token.deleted An API token was deleted.
environment.created An environment was created.
environment.renamed An environment was renamed.
environment.deleted An environment was deleted. Its lines move to Production and its tokens are revoked.
webhook_subscription.created A webhook subscription was created.
webhook_subscription.deleted A webhook subscription was deleted.
webhook_subscription.target_url_changed A subscription’s URL changed. URLs are sent without credentials, query string or fragment.
webhook_subscription.enabled A subscription was enabled.
webhook_subscription.disabled A subscription was disabled.
webhook_subscription.events.updated A subscription’s event list changed. change values are the full old and new lists.
webhook_subscription.phone_numbers.updated A subscription’s line filter changed. change values are the full old and new lists; an empty list means every line.
webhook_subscription.routing_headers_set Routing headers were set on a subscription.
webhook_subscription.routing_headers_cleared Routing headers were removed from a subscription.
team_member.added Someone was added to your account, including by invite or directory sync.
team_member.signed_in A team member signed in. method says how.
team_member.signed_out A team member signed out.

Every account event’s data carries summary, occurred_at, actor and origin. Depending on the event, it can also include the affected api_token, environment, webhook_subscription, contact_card, phone_number or team_member. Environments are identified by name (Production is {"name": "Production", "type": "environment"}); api_token.expires_at is always present, null when the token never expires.

  • Most update events add change: {from, to}. from: null means the value was first set and to: null means it was cleared. For contact_card.updated, change instead carries first_name, last_name and/or image_url, each a {from, to} present only when that field changed.
  • Created and deleted events have no change. Neither do enabled, disabled, expired and activated events.
  • actor is who made the change: team_member (with id, name and email), api, system (a change made by Linq), or unknown.
  • origin is where the change was made: dashboard, api or linq.
  • summary matches the Activity page label. It is for display only; the wording may change.

The value types inside change differ per event; each event below has a full example, and the API Reference: Webhook Events has the schema.

  • event_id is the deduplication key. It is the same on every retry and on every subscription the event is delivered to.
  • No ordering guarantee. Use data.occurred_at to order changes, not arrival time.
  • Best-effort. If a delivery still fails after retries, the change remains on your Activity page, which is the record of account changes.
  • Environments. A change inside an environment goes to that environment’s subscriptions; environment.line_moved goes to the environment the line joined. Account-wide changes, environment lifecycle events and team member events go to Production subscriptions. A subscription’s phone_numbers filter does not apply to account events.
  • Your own subscription. webhook_subscription.* events include changes to the subscription receiving them: if a subscription already listens for an event, it gets that event about its own URL, event list, line filter or routing headers changing. webhook_subscription.deleted and .disabled go only to your other subscriptions.

Fires when your account’s zero-day retention setting is turned on or off. change.from and change.to are booleans.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "zero_day_retention.updated",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0001",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Zero-day retention turned on",
"occurred_at": "2026-09-25T18:23:44.201Z",
"change": {
"from": false,
"to": true
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when a line’s call forwarding number changes. change.from and change.to are E.164 numbers.

When forwarding is turned off, change.to is null; when the line had no forwarding number before, change.from is null.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "phone_number.forwarding_updated",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0003",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Line forwarding number changed",
"occurred_at": "2026-09-25T18:23:44.201Z",
"phone_number": "+12025551234",
"change": {
"from": "+12025550199",
"to": "+12025550100"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when a line moves to another environment. change.from is the environment it left and change.to the one it joined, each identified by name. Delivered to subscriptions in the destination environment.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "environment.line_moved",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0004",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Line moved to environment",
"occurred_at": "2026-09-25T18:23:44.201Z",
"phone_number": "+12025551234",
"change": {
"from": {
"name": "Production",
"type": "environment"
},
"to": {
"name": "Staging",
"type": "environment"
}
},
"actor": {
"type": "api"
},
"origin": "api"
}
}

Fires when a contact card is created for a line. contact_card is the card that was created. There is no change.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "contact_card.created",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0005",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Contact card created",
"occurred_at": "2026-09-25T18:23:44.201Z",
"phone_number": "+12025551234",
"contact_card": {
"id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
"first_name": "Acme",
"last_name": "Support",
"image_url": null
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when a contact card’s name or photo changes.

contact_card is the card after the change. change carries first_name, last_name and/or image_url, each present only when that field changed; their from and to are strings, null when the card had or has none.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "contact_card.updated",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0006",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Contact card updated",
"occurred_at": "2026-09-25T18:23:44.201Z",
"phone_number": "+12025551234",
"contact_card": {
"id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
"first_name": "Acme",
"last_name": "Support",
"image_url": "https://cdn.linqapp.com/contact-card/example.jpg"
},
"change": {
"last_name": {
"from": null,
"to": "Support"
},
"image_url": {
"from": null,
"to": "https://cdn.linqapp.com/contact-card/example.jpg"
}
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when a contact card is deleted. contact_card is the card that was deleted. There is no change.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "contact_card.deleted",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0007",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Contact card deleted",
"occurred_at": "2026-09-25T18:23:44.201Z",
"phone_number": "+12025551234",
"contact_card": {
"id": "c3d4e5f6-a7b8-4c9d-8e0f-1a2b3c4d5e6f",
"first_name": "Acme",
"last_name": "Support",
"image_url": "https://cdn.linqapp.com/contact-card/example.jpg"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when an API token is created. token_prefix identifies the token without revealing it (it is on every api_token.* event), and expires_at is null if it never expires. There is no change.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "api_token.created",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0008",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "API token created",
"occurred_at": "2026-09-25T18:23:44.201Z",
"api_token": {
"id": "7c1e2f3a-4b5c-4d6e-8f90-1a2b3c4d5e6f",
"name": "CI deploy",
"token_prefix": "lq_live_3f9a",
"expires_at": "2027-03-25T00:00:00Z"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when an API token is renamed. change.from and change.to are the old and new names, null when the token had or has no name.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "api_token.renamed",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0009",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "API token renamed",
"occurred_at": "2026-09-25T18:23:44.201Z",
"api_token": {
"id": "7c1e2f3a-4b5c-4d6e-8f90-1a2b3c4d5e6f",
"name": "CI deploy",
"token_prefix": "lq_live_3f9a",
"expires_at": null
},
"change": {
"from": "Deploy key",
"to": "CI deploy"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when an API token is set to expire at a future time. change.from and change.to are timestamps, null meaning the token never expires; from is null when this is the token’s first expiry.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "api_token.expiry_scheduled",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0010",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "API token expiry scheduled",
"occurred_at": "2026-09-25T18:23:44.201Z",
"api_token": {
"id": "7c1e2f3a-4b5c-4d6e-8f90-1a2b3c4d5e6f",
"name": "CI deploy",
"token_prefix": "lq_live_3f9a",
"expires_at": "2026-12-31T00:00:00Z"
},
"change": {
"from": null,
"to": "2026-12-31T00:00:00Z"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when an API token is expired immediately. Requests with this token are rejected from api_token.expires_at. There is no change.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "api_token.expired",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0011",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "API token expired",
"occurred_at": "2026-09-25T18:23:44.201Z",
"api_token": {
"id": "7c1e2f3a-4b5c-4d6e-8f90-1a2b3c4d5e6f",
"name": "CI deploy",
"token_prefix": "lq_live_3f9a",
"expires_at": "2026-09-25T18:23:44Z"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when an expired or expiring API token is made active again with no expiry, so expires_at is null. There is no change.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "api_token.activated",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0012",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "API token activated",
"occurred_at": "2026-09-25T18:23:44.201Z",
"api_token": {
"id": "7c1e2f3a-4b5c-4d6e-8f90-1a2b3c4d5e6f",
"name": "CI deploy",
"token_prefix": "lq_live_3f9a",
"expires_at": null
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when an API token is deleted. token_prefix identifies the token without revealing it. There is no change.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "api_token.deleted",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0013",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "API token deleted",
"occurred_at": "2026-09-25T18:23:44.201Z",
"api_token": {
"id": "7c1e2f3a-4b5c-4d6e-8f90-1a2b3c4d5e6f",
"name": "CI deploy",
"token_prefix": "lq_live_3f9a",
"expires_at": "2027-03-25T00:00:00Z"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when an environment is created. There is no change. Delivered to Production subscriptions.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "environment.created",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0014",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Environment created",
"occurred_at": "2026-09-25T18:23:44.201Z",
"environment": {
"name": "Staging",
"type": "environment"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when an environment is renamed. change.from and change.to are the old and new names. Delivered to Production subscriptions.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "environment.renamed",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0015",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Environment renamed",
"occurred_at": "2026-09-25T18:23:44.201Z",
"environment": {
"name": "Staging",
"type": "environment"
},
"change": {
"from": "QA",
"to": "Staging"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when an environment is permanently deleted: its lines move to Production and its tokens are revoked. lines_moved_to_production and tokens_revoked count each. There is no change. Delivered to Production subscriptions.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "environment.deleted",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0017",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Environment deleted",
"occurred_at": "2026-09-25T18:23:44.201Z",
"environment": {
"name": "Staging",
"type": "environment"
},
"lines_moved_to_production": 3,
"tokens_revoked": 2,
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when a webhook subscription is created. webhook_subscription.events is what the new subscription listens for. There is no change.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "webhook_subscription.created",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0018",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Webhook created",
"occurred_at": "2026-09-25T18:23:44.201Z",
"webhook_subscription": {
"id": "b2f4c6d8-1a3e-4c5f-9e7d-3b5a7c9e1f20",
"target_url": "https://hooks.example.com/linq",
"events": [
"message.received",
"webhook_subscription.created"
]
},
"actor": {
"type": "api"
},
"origin": "api"
}
}

Fires when a webhook subscription is deleted. There is no change. Delivered only to your other subscriptions.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "webhook_subscription.deleted",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0019",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Webhook deleted",
"occurred_at": "2026-09-25T18:23:44.201Z",
"webhook_subscription": {
"id": "b2f4c6d8-1a3e-4c5f-9e7d-3b5a7c9e1f20",
"target_url": "https://hooks.example.com/linq"
},
"actor": {
"type": "api"
},
"origin": "api"
}
}

Fires when a webhook subscription’s URL changes. change.from and change.to are the old and new URLs, sent without credentials, query string or fragment.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "webhook_subscription.target_url_changed",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0020",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Webhook URL changed",
"occurred_at": "2026-09-25T18:23:44.201Z",
"webhook_subscription": {
"id": "b2f4c6d8-1a3e-4c5f-9e7d-3b5a7c9e1f20"
},
"change": {
"from": "https://old.example.com/linq",
"to": "https://hooks.example.com/linq"
},
"actor": {
"type": "api"
},
"origin": "api"
}
}

Fires when a webhook subscription is enabled. There is no change.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "webhook_subscription.enabled",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0021",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Webhook enabled",
"occurred_at": "2026-09-25T18:23:44.201Z",
"webhook_subscription": {
"id": "b2f4c6d8-1a3e-4c5f-9e7d-3b5a7c9e1f20",
"target_url": "https://hooks.example.com/linq"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when a webhook subscription is disabled. There is no change. Delivered only to your other subscriptions.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "webhook_subscription.disabled",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0022",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Webhook disabled",
"occurred_at": "2026-09-25T18:23:44.201Z",
"webhook_subscription": {
"id": "b2f4c6d8-1a3e-4c5f-9e7d-3b5a7c9e1f20",
"target_url": "https://hooks.example.com/linq"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when a webhook subscription’s event list changes. change.from and change.to are the full old and new lists of event types.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "webhook_subscription.events.updated",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0023",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Webhook events changed",
"occurred_at": "2026-09-25T18:23:44.201Z",
"webhook_subscription": {
"id": "b2f4c6d8-1a3e-4c5f-9e7d-3b5a7c9e1f20"
},
"change": {
"from": [
"message.received",
"webhook_subscription.events.updated"
],
"to": [
"message.received",
"message.sent",
"webhook_subscription.events.updated"
]
},
"actor": {
"type": "api"
},
"origin": "api"
}
}

webhook_subscription.phone_numbers.updated

Section titled “webhook_subscription.phone_numbers.updated”

Fires when a webhook subscription’s line filter changes. change.from and change.to are the full old and new lists of E.164 numbers; an empty list means every line.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "webhook_subscription.phone_numbers.updated",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0024",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Webhook lines changed",
"occurred_at": "2026-09-25T18:23:44.201Z",
"webhook_subscription": {
"id": "b2f4c6d8-1a3e-4c5f-9e7d-3b5a7c9e1f20"
},
"change": {
"from": [],
"to": [
"+12025551234",
"+12025555678"
]
},
"actor": {
"type": "api"
},
"origin": "api"
}
}

Fires when routing headers are set on a webhook subscription. change.to is the new headers, {key_header, id_header?}; change.from is the headers they replaced, or null when they were first set.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "webhook_subscription.routing_headers_set",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0025",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Webhook routing headers set",
"occurred_at": "2026-09-25T18:23:44.201Z",
"webhook_subscription": {
"id": "b2f4c6d8-1a3e-4c5f-9e7d-3b5a7c9e1f20"
},
"change": {
"from": null,
"to": {
"key_header": "X-Routing-Key",
"id_header": "X-Routing-Id"
}
},
"actor": {
"type": "api"
},
"origin": "api"
}
}

webhook_subscription.routing_headers_cleared

Section titled “webhook_subscription.routing_headers_cleared”

Fires when routing headers are removed from a webhook subscription. change.from is the headers that were removed, {key_header, id_header?}, and change.to is always null.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "webhook_subscription.routing_headers_cleared",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d0026",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Webhook routing headers cleared",
"occurred_at": "2026-09-25T18:23:44.201Z",
"webhook_subscription": {
"id": "b2f4c6d8-1a3e-4c5f-9e7d-3b5a7c9e1f20"
},
"change": {
"from": {
"key_header": "X-Routing-Key",
"id_header": "X-Routing-Id"
},
"to": null
},
"actor": {
"type": "api"
},
"origin": "api"
}
}

Fires when someone is added to your account, including by invite or directory sync. Not sent when an existing member’s role changes. Delivered to Production subscriptions.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "team_member.added",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d001b",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Team member added",
"occurred_at": "2026-09-25T18:23:44.201Z",
"team_member": {
"id": "3f6c9a52-8d1e-4b7a-a2c4-9e0f5d7b1c38",
"name": "Sam Rivera",
"role": "member"
},
"actor": {
"type": "team_member",
"id": "8d2e4f60-1b3c-4a5d-9e7f-0a1b2c3d4e5f",
"name": "Maria Lopez",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when a team member signs in. method is how they signed in: code (a one-time code sent by email or text), sso, google, apple or linkedin. A member of several accounts triggers one event per account. Delivered to Production subscriptions.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "team_member.signed_in",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d001c",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Team member signed in",
"occurred_at": "2026-09-25T18:23:44.201Z",
"team_member": {
"id": "3f6c9a52-8d1e-4b7a-a2c4-9e0f5d7b1c38",
"name": "Sam Rivera"
},
"method": "sso",
"actor": {
"type": "team_member",
"id": "3f6c9a52-8d1e-4b7a-a2c4-9e0f5d7b1c38",
"name": "Sam Rivera",
"email": "[email protected]"
},
"origin": "dashboard"
}
}

Fires when a team member signs out. A member of several accounts triggers one event per account. Delivered to Production subscriptions.

{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "team_member.signed_out",
"event_id": "5b2f0c1e-7a41-4d7e-9a53-0f6f1c9d001d",
"created_at": "2026-09-25T18:23:44.512Z",
"trace_id": "4f9a1c0d2b3e4f5a6b7c8d9e0f1a2b3c",
"partner_id": "your-partner-id",
"data": {
"summary": "Team member signed out",
"occurred_at": "2026-09-25T18:23:44.201Z",
"team_member": {
"id": "3f6c9a52-8d1e-4b7a-a2c4-9e0f5d7b1c38",
"name": "Sam Rivera"
},
"actor": {
"type": "team_member",
"id": "3f6c9a52-8d1e-4b7a-a2c4-9e0f5d7b1c38",
"name": "Sam Rivera",
"email": "[email protected]"
},
"origin": "dashboard"
}
}