Skip to content
LinqCopy 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, 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.

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": { ... }
}
FieldDescription
api_versionAPI version (v3)
webhook_versionPayload version (2025-01-01 or 2026-02-03)
event_typeEvent type string
event_idUnique event ID (use for deduplication)
created_atWhen the event was created
trace_idTrace ID for debugging
partner_idYour partner identifier
dataEvent-specific payload
EventDescription
message.sentMessage successfully sent from your phone number
message.receivedIncoming message received on your phone number
message.deliveredMessage delivered to recipient’s device
message.readMessage read by recipient
message.failedMessage delivery failed
message.editedMessage 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.

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/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/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/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/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/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"
}
}
EventDescription
reaction.addedReaction (tapback) added to a message — see Reactions
reaction.removedReaction 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 emojireaction_type: "custom", emoji in custom_emoji
  • Stickerreaction_type: "sticker", details in a sticker object — see Sticker attachments

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.addedreacted_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
}
}
EventDescription
poll.receivedA participant sent a poll to your line — see Polls
poll.sentA poll you created left the device
poll.deliveredThat poll reached the recipient
poll.readThe recipient read it
poll.updatedOptions were added to an existing poll
poll.failedAn outbound poll or poll action failed to send
poll.vote.addedA participant voted for an option
poll.vote.removedA participant took a vote back
poll.reaction.addedSomeone 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
}
}
EventDescription
chat.createdNew chat created — fires for DMs and group chats
chat.group_name_updatedGroup chat display name changed
chat.group_icon_updatedGroup chat icon changed
chat.group_name_update_failedGroup name update failed
chat.group_icon_update_failedGroup icon update failed
chat.background_updatedChat transcript background set, changed, or removed — see Chat Backgrounds
chat.background_update_failedBackground set or removal failed
chat.typing_indicator.startedParticipant started typing — see Typing Indicators
chat.typing_indicator.stoppedParticipant 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/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"
}
}
EventDescription
participant.addedParticipant added to a group chat
participant.removedParticipant 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"
}
}
EventDescription
phone_number.status_updatedPhone number status (ACTIVEFLAGGED) or reputation (HEALTHY / AT_RISK / CRITICAL) changed — see Phone Numbers and Phone Reputation

Fires when a phone number’s service status (ACTIVEFLAGGED) 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"
}
}
EventDescription
location.sharing.startedA participant started sharing their location with you — see Location Sharing
location.sharing.stoppedA participant stopped sharing their location

Both payloads carry shared_by (their phone number — or Apple ID email if they shared from the standalone Find My app, see Location Sharing) and shared_with (your number). location.sharing.started also includes began_at, and ends_at when sharing is time-boxed. 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"
}
}

Fires when a participant stops sharing their location.

{
"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"
}
}