Skip to content
V2 (Legacy) API ReferenceGet started

Get a message by ID

client.messages.retrieve(stringmessageID, RequestOptionsoptions?): Message { id, chat_id, created_at, 14 more }
GET/v3/messages/{messageId}

Retrieve a specific message by its ID. This endpoint returns the full message details including text, attachments, reactions, and metadata.

ParametersExpand Collapse
messageID: string
formatuuid
ReturnsExpand Collapse
Message { id, chat_id, created_at, 14 more }
id: string

Unique identifier for the message

formatuuid
chat_id: string

ID of the chat this message belongs to

formatuuid
created_at: string

When the message was created

formatdate-time
is_delivered: boolean

Whether the message has been delivered

is_from_me: boolean

Whether this message was sent by the authenticated user

is_read: boolean

Whether the message has been read

updated_at: string

When the message was last updated

formatdate-time
delivered_at?: string | null

When the message was delivered

formatdate-time
effect?: MessageEffect { name, type } | null

iMessage effect applied to a message (screen or bubble effect)

name?: string

Name of the effect. Common values:

  • Screen effects: confetti, fireworks, lasers, sparkles, celebration, hearts, love, balloons, happy_birthday, echo, spotlight
  • Bubble effects: slam, loud, gentle, invisible
type?: "screen" | "bubble"

Type of effect

One of the following:
"screen"
"bubble"
Deprecatedfrom?: string | null

DEPRECATED: Use from_handle instead. Phone number of the message sender.

from_handle?: ChatHandle { id, handle, joined_at, 4 more } | null

The sender of this message as a full handle object

id: string

Unique identifier for this handle

formatuuid
handle: string

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

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
is_me?: boolean | null

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

left_at?: string | null

When they left (if applicable)

formatdate-time
status?: "active" | "left" | "removed" | null

Participant status

One of the following:
"active"
"left"
"removed"
parts?: Array<TextPartResponse { reactions, type, value, text_decorations } | MediaPartResponse { id, filename, mime_type, 4 more } | LinkPartResponse { reactions, type, value } > | null

Message parts in order (text, media, and link)

One of the following:
TextPartResponse { reactions, type, value, text_decorations }

A text message part

reactions: Array<Reaction { handle, is_me, type, 2 more } > | null

Reactions on this message part

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

Unique identifier for this handle

formatuuid
handle: string

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

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
is_me?: boolean | null

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

left_at?: string | null

When they left (if applicable)

formatdate-time
status?: "active" | "left" | "removed" | null

Participant status

One of the following:
"active"
"left"
"removed"
is_me: boolean

Whether this reaction is from the current user

Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type โ€œcustomโ€ with the actual emoji in the custom_emoji field. Sticker reactions have type โ€œstickerโ€ with sticker attachment details in the sticker field.

One of the following:
"love"
"like"
"dislike"
"laugh"
"emphasize"
"question"
"custom"
"sticker"
custom_emoji?: string | null

Custom emoji if type is โ€œcustomโ€, null otherwise

sticker?: Sticker | null

Sticker attachment details when reaction_type is โ€œstickerโ€. Null for non-sticker reactions.

file_name?: string

Filename of the sticker

height?: number

Sticker image height in pixels

mime_type?: string

MIME type of the sticker image

url?: string

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

formaturi
width?: number

Sticker image width in pixels

type: "text"

Indicates this is a text message part

value: string

The text content

text_decorations?: Array<TextDecoration { range, animation, style } > | null

Text decorations applied to character ranges in the value

range: Array<number>

Character range [start, end) in the value string where the decoration applies. start is inclusive, end is exclusive. Characters are measured as UTF-16 code units. Most characters count as 1; some emoji count as 2.

animation?: "big" | "small" | "shake" | 5 more

Animated text effect to apply. Mutually exclusive with style.

One of the following:
"big"
"small"
"shake"
"nod"
"explode"
"ripple"
"bloom"
"jitter"
style?: "bold" | "italic" | "strikethrough" | "underline"

Text style to apply. Mutually exclusive with animation.

One of the following:
"bold"
"italic"
"strikethrough"
"underline"
MediaPartResponse { id, filename, mime_type, 4 more }

A media attachment part

id: string

Unique attachment identifier

formatuuid
filename: string

Original filename

mime_type: string

MIME type of the file

reactions: Array<Reaction { handle, is_me, type, 2 more } > | null

Reactions on this message part

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

Unique identifier for this handle

formatuuid
handle: string

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

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
is_me?: boolean | null

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

left_at?: string | null

When they left (if applicable)

formatdate-time
status?: "active" | "left" | "removed" | null

Participant status

One of the following:
"active"
"left"
"removed"
is_me: boolean

Whether this reaction is from the current user

Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type โ€œcustomโ€ with the actual emoji in the custom_emoji field. Sticker reactions have type โ€œstickerโ€ with sticker attachment details in the sticker field.

One of the following:
"love"
"like"
"dislike"
"laugh"
"emphasize"
"question"
"custom"
"sticker"
custom_emoji?: string | null

Custom emoji if type is โ€œcustomโ€, null otherwise

sticker?: Sticker | null

Sticker attachment details when reaction_type is โ€œstickerโ€. Null for non-sticker reactions.

file_name?: string

Filename of the sticker

height?: number

Sticker image height in pixels

mime_type?: string

MIME type of the sticker image

url?: string

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

formaturi
width?: number

Sticker image width in pixels

size_bytes: number

File size in bytes

type: "media"

Indicates this is a media attachment part

url: string

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

formaturi
handle: ChatHandle { id, handle, joined_at, 4 more }
id: string

Unique identifier for this handle

formatuuid
handle: string

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

joined_at: string

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
is_me?: boolean | null

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

left_at?: string | null

When they left (if applicable)

formatdate-time
status?: "active" | "left" | "removed" | null

Participant status

One of the following:
"active"
"left"
"removed"
is_me: boolean

Whether this reaction is from the current user

Type of reaction. Standard iMessage tapbacks are love, like, dislike, laugh, emphasize, question. Custom emoji reactions have type โ€œcustomโ€ with the actual emoji in the custom_emoji field. Sticker reactions have type โ€œstickerโ€ with sticker attachment details in the sticker field.

One of the following:
"love"
"like"
"dislike"
"laugh"
"emphasize"
"question"
"custom"
"sticker"
custom_emoji?: string | null

Custom emoji if type is โ€œcustomโ€, null otherwise

sticker?: Sticker | null

Sticker attachment details when reaction_type is โ€œstickerโ€. Null for non-sticker reactions.

file_name?: string

Filename of the sticker

height?: number

Sticker image height in pixels

mime_type?: string

MIME type of the sticker image

url?: string

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

formaturi
width?: number

Sticker image width in pixels

preferred_service?: ServiceType | null

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
read_at?: string | null

When the message was read

formatdate-time
reply_to?: ReplyTo { message_id, part_index } | null

Indicates this message is a threaded reply to another message

message_id: string

The ID of the message to reply to

formatuuid
part_index?: number

The specific message part to reply to (0-based index). Defaults to 0 (first part) if not provided. Use this when replying to a specific part of a multipart message.

formatint32
minimum0
sent_at?: string | null

When the message was sent

formatdate-time
service?: ServiceType | null

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"

Get a message by ID

import LinqAPIV3 from '@linqapp/sdk';

const client = new LinqAPIV3({
  apiKey: process.env['LINQ_API_V3_API_KEY'], // This is the default and can be omitted
});

const message = await client.messages.retrieve('69a37c7d-af4f-4b5e-af42-e28e98ce873a');

console.log(message.id);
{
  "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a",
  "chat_id": "94c6bf33-31d9-40e3-a0e9-f94250ecedb9",
  "created_at": "2024-01-15T10:30:00Z",
  "is_delivered": true,
  "is_from_me": true,
  "is_read": false,
  "updated_at": "2024-01-15T10:30:00Z",
  "delivered_at": "2024-01-15T10:30:10Z",
  "effect": {
    "name": "confetti",
    "type": "screen"
  },
  "from": "+12052535597",
  "from_handle": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "handle": "+15551234567",
    "joined_at": "2025-05-21T15:30:00.000-05:00",
    "service": "iMessage",
    "is_me": false,
    "left_at": "2019-12-27T18:11:19.117Z",
    "status": "active"
  },
  "parts": [
    {
      "reactions": [
        {
          "handle": {
            "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a",
            "handle": "+15551234567",
            "joined_at": "2025-05-21T15:30:00.000-05:00",
            "service": "iMessage",
            "is_me": false,
            "left_at": "2019-12-27T18:11:19.117Z",
            "status": "active"
          },
          "is_me": false,
          "type": "love",
          "custom_emoji": null,
          "sticker": {
            "file_name": "sticker.png",
            "height": 420,
            "mime_type": "image/png",
            "url": "https://cdn.linqapp.com/attachments/a1b2c3d4/sticker.png?signature=...",
            "width": 420
          }
        }
      ],
      "type": "text",
      "value": "Hello!",
      "text_decorations": [
        {
          "range": [
            0,
            5
          ],
          "animation": "shake",
          "style": "bold"
        }
      ]
    }
  ],
  "preferred_service": "iMessage",
  "read_at": "2024-01-15T10:35:00Z",
  "reply_to": {
    "message_id": "550e8400-e29b-41d4-a716-446655440000",
    "part_index": 0
  },
  "sent_at": "2024-01-15T10:30:05Z",
  "service": "iMessage"
}
{
  "error": {
    "status": 401,
    "code": 2004,
    "message": "Unauthorized - missing or invalid authentication token"
  },
  "success": false
}
{
  "error": {
    "status": 403,
    "code": 2005,
    "message": "Access denied - insufficient permissions for this resource"
  },
  "success": false
}
{
  "error": {
    "status": 404,
    "code": 2001,
    "message": "Resource not found"
  },
  "success": false
}
{
  "error": {
    "status": 500,
    "code": 3006,
    "message": "Internal server error"
  },
  "success": false
}
Returns Examples
{
  "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a",
  "chat_id": "94c6bf33-31d9-40e3-a0e9-f94250ecedb9",
  "created_at": "2024-01-15T10:30:00Z",
  "is_delivered": true,
  "is_from_me": true,
  "is_read": false,
  "updated_at": "2024-01-15T10:30:00Z",
  "delivered_at": "2024-01-15T10:30:10Z",
  "effect": {
    "name": "confetti",
    "type": "screen"
  },
  "from": "+12052535597",
  "from_handle": {
    "id": "550e8400-e29b-41d4-a716-446655440000",
    "handle": "+15551234567",
    "joined_at": "2025-05-21T15:30:00.000-05:00",
    "service": "iMessage",
    "is_me": false,
    "left_at": "2019-12-27T18:11:19.117Z",
    "status": "active"
  },
  "parts": [
    {
      "reactions": [
        {
          "handle": {
            "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a",
            "handle": "+15551234567",
            "joined_at": "2025-05-21T15:30:00.000-05:00",
            "service": "iMessage",
            "is_me": false,
            "left_at": "2019-12-27T18:11:19.117Z",
            "status": "active"
          },
          "is_me": false,
          "type": "love",
          "custom_emoji": null,
          "sticker": {
            "file_name": "sticker.png",
            "height": 420,
            "mime_type": "image/png",
            "url": "https://cdn.linqapp.com/attachments/a1b2c3d4/sticker.png?signature=...",
            "width": 420
          }
        }
      ],
      "type": "text",
      "value": "Hello!",
      "text_decorations": [
        {
          "range": [
            0,
            5
          ],
          "animation": "shake",
          "style": "bold"
        }
      ]
    }
  ],
  "preferred_service": "iMessage",
  "read_at": "2024-01-15T10:35:00Z",
  "reply_to": {
    "message_id": "550e8400-e29b-41d4-a716-446655440000",
    "part_index": 0
  },
  "sent_at": "2024-01-15T10:30:05Z",
  "service": "iMessage"
}
{
  "error": {
    "status": 401,
    "code": 2004,
    "message": "Unauthorized - missing or invalid authentication token"
  },
  "success": false
}
{
  "error": {
    "status": 403,
    "code": 2005,
    "message": "Access denied - insufficient permissions for this resource"
  },
  "success": false
}
{
  "error": {
    "status": 404,
    "code": 2001,
    "message": "Resource not found"
  },
  "success": false
}
{
  "error": {
    "status": 500,
    "code": 3006,
    "message": "Internal server error"
  },
  "success": false
}