Skip to content
Linq Copy agent prompt

Sender Devices

Tell when a contact messages you from a device you haven't seen them use before.

Every inbound iMessage on a message.received webhook carries device_status, which compares the sender’s device with the devices they have messaged you from before, and device_first_seen_at, the time that device first messaged you.

Values: first_contact , known , new .

Value Meaning device_first_seen_at
first_contact The first message you’ve received from this sender, so there’s no earlier device to compare. This message’s time
known A device this sender has messaged you from before. When that device first messaged you
new A device you haven’t seen for a sender who has already messaged you from another one. This message’s time

Devices are tracked per sender across every line on your account. A message from a known contact to a line they’ve never texted reads as known when it comes from a device they’ve already used with you.

Both fields are on message.received for iMessage only. They are absent on SMS and RCS messages, on outbound events (message.sent, message.delivered, message.read), and on any inbound iMessage that arrives without device information.

Webhook version Location
2026-02-03 data.device_status, data.device_first_seen_at
2025-01-01 data.message.device_status, data.message.device_first_seen_at
{
"api_version": "v3",
"webhook_version": "2026-02-03",
"event_type": "message.received",
"event_id": "2915e81c-5068-4796-ace2-21d2c94ad298",
"created_at": "2026-10-23T17:29:56.118Z",
"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-10-23T17:29:55.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": "Hi, I need to change the bank account on my payouts"
}
],
"device_status": "new",
"device_first_seen_at": "2026-10-23T17:29:55Z",
"effect": null,
"reply_to": null,
"sent_at": "2026-10-23T17:29:55Z",
"delivered_at": null,
"read_at": null,
"service": "iMessage"
}
}
import LinqAPIV3 from '@linqapp/sdk';
const client = new LinqAPIV3();
// In your webhook handler (2026-02-03 subscription):
const event = client.webhooks.unwrap(rawBody, { headers: req.headers });
if (event.event_type === 'message.received' && event.data.device_status === 'new') {
await handleNewDevice({
handle: event.data.sender_handle.handle,
chatId: event.data.chat.id,
deviceFirstSeenAt: event.data.device_first_seen_at,
});
}