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.
device_status
Section titled “device_status”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.
Where the fields appear
Section titled “Where the fields appear”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" }}Read device_status in a webhook handler
Section titled “Read device_status in a webhook handler”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, });}from linq import LinqAPIV3
client = LinqAPIV3()
# In your webhook handler (2026-02-03 subscription):event = client.webhooks.unwrap(raw_body, headers=request.headers)
if event.event_type == "message.received" and event.data.device_status == "new": handle_new_device( handle=event.data.sender_handle.handle, chat_id=event.data.chat.id, device_first_seen_at=event.data.device_first_seen_at, )Related
Section titled “Related”- Webhook Events:
message.received— the full payload - Webhooks — setup, signature verification, and webhook versions
- Protocol Selection — which messages arrive over iMessage, SMS, or RCS
- API Reference: Webhook Events — the
message.receivedschema