Skip to content
Get started

Get all messages in a thread

messages.list_messages_thread(strmessage_id, MessageListMessagesThreadParams**kwargs) -> SyncListMessagesPagination[Message]
GET/v3/messages/{messageId}/thread

Retrieve all messages in a conversation thread. Given any message ID in the thread, returns the originator message and all replies in chronological order.

If the message is not part of a thread, returns just that single message.

Supports pagination and configurable ordering.

ParametersExpand Collapse
message_id: str
formatuuid
cursor: Optional[str]

Pagination cursor from previous next_cursor response

limit: Optional[int]

Maximum number of messages to return

minimum1
maximum100
order: Optional[Literal["asc", "desc"]]

Sort order for messages (asc = oldest first, desc = newest first)

One of the following:
"asc"
"desc"
ReturnsExpand Collapse
class Message:
id: str

Unique identifier for the message

formatuuid
chat_id: str

ID of the chat this message belongs to

formatuuid
created_at: datetime

When the message was created

formatdate-time
delivery_status: Literal["pending", "queued", "sent", 4 more]

Current delivery status of a message

One of the following:
"pending"
"queued"
"sent"
"delivered"
"received"
"read"
"failed"
Deprecatedis_delivered: bool

DEPRECATED: Use delivery_status instead (true when delivery_status is delivered or read). Whether the message has been delivered.

is_from_me: bool

Whether this message was sent by the authenticated user

Deprecatedis_read: bool

DEPRECATED: Use delivery_status == "read" instead. Whether the message has been read.

updated_at: datetime

When the message was last updated

formatdate-time
delivered_at: Optional[datetime]

When the message was delivered

formatdate-time
effect: Optional[MessageEffect]

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

name: Optional[str]

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: Optional[Literal["screen", "bubble"]]

Type of effect

One of the following:
"screen"
"bubble"
Deprecatedfrom_: Optional[str]

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

from_handle: Optional[ChatHandle]

The sender of this message as a full handle object

id: str

Unique identifier for this handle

formatuuid
handle: str

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

joined_at: datetime

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
is_me: Optional[bool]

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

left_at: Optional[datetime]

When they left (if applicable)

formatdate-time
status: Optional[Literal["active", "left", "removed"]]

Participant status

One of the following:
"active"
"left"
"removed"
parts: Optional[List[Part]]

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

One of the following:
class TextPartResponse:

A text message part

reactions: Optional[List[Reaction]]

Reactions on this message part

handle: ChatHandle
id: str

Unique identifier for this handle

formatuuid
handle: str

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

joined_at: datetime

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
is_me: Optional[bool]

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

left_at: Optional[datetime]

When they left (if applicable)

formatdate-time
status: Optional[Literal["active", "left", "removed"]]

Participant status

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

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: Optional[str]

Custom emoji if type is “custom”, null otherwise

sticker: Optional[Sticker]

Sticker attachment details when reaction_type is “sticker”. Null for non-sticker reactions.

file_name: Optional[str]

Filename of the sticker

height: Optional[int]

Sticker image height in pixels

mime_type: Optional[str]

MIME type of the sticker image

url: Optional[str]

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

formaturi
width: Optional[int]

Sticker image width in pixels

type: Literal["text"]

Indicates this is a text message part

value: str

The text content

text_decorations: Optional[List[TextDecoration]]

Text decorations applied to character ranges in the value

range: List[int]

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: Optional[Literal["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: Optional[Literal["bold", "italic", "strikethrough", "underline"]]

Text style to apply. Mutually exclusive with animation.

One of the following:
"bold"
"italic"
"strikethrough"
"underline"
class MediaPartResponse:

A media attachment part

id: str

Unique attachment identifier

formatuuid
filename: str

Original filename

mime_type: str

MIME type of the file

reactions: Optional[List[Reaction]]

Reactions on this message part

handle: ChatHandle
id: str

Unique identifier for this handle

formatuuid
handle: str

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

joined_at: datetime

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
is_me: Optional[bool]

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

left_at: Optional[datetime]

When they left (if applicable)

formatdate-time
status: Optional[Literal["active", "left", "removed"]]

Participant status

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

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: Optional[str]

Custom emoji if type is “custom”, null otherwise

sticker: Optional[Sticker]

Sticker attachment details when reaction_type is “sticker”. Null for non-sticker reactions.

file_name: Optional[str]

Filename of the sticker

height: Optional[int]

Sticker image height in pixels

mime_type: Optional[str]

MIME type of the sticker image

url: Optional[str]

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

formaturi
width: Optional[int]

Sticker image width in pixels

size_bytes: int

File size in bytes

type: Literal["media"]

Indicates this is a media attachment part

url: str

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

formaturi
handle: ChatHandle
id: str

Unique identifier for this handle

formatuuid
handle: str

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

joined_at: datetime

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
is_me: Optional[bool]

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

left_at: Optional[datetime]

When they left (if applicable)

formatdate-time
status: Optional[Literal["active", "left", "removed"]]

Participant status

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

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: Optional[str]

Custom emoji if type is “custom”, null otherwise

sticker: Optional[Sticker]

Sticker attachment details when reaction_type is “sticker”. Null for non-sticker reactions.

file_name: Optional[str]

Filename of the sticker

height: Optional[int]

Sticker image height in pixels

mime_type: Optional[str]

MIME type of the sticker image

url: Optional[str]

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

formaturi
width: Optional[int]

Sticker image width in pixels

class PartiMessageAppPartResponse:

An iMessage app card part.

app: PartiMessageAppPartResponseApp

Identifies the iMessage app (Messages app extension) that backs the card.

bundle_id: str

Bundle identifier of the Messages app extension. Must not contain :.

minLength1
maxLength255
name: str

Display name of the app, shown by Messages’ fallback UI.

minLength1
maxLength64
team_id: str

The app’s 10-character uppercase alphanumeric team identifier.

app_store_id: Optional[int]

The owning app’s App Store id (optional). When set, recipients without the iMessage app installed see a “Get the app” affordance.

formatint64
minimum1
layout: PartiMessageAppPartResponseLayout

Visible layout of the card. At least one of caption, subcaption, trailing_caption, or trailing_subcaption must be set, otherwise the card renders as an empty bubble. Any image on the card is drawn by the recipient’s installed app extension; it cannot be supplied here.

caption: Optional[str]

Primary label, top-left and bold.

maxLength512
subcaption: Optional[str]

Secondary label, below caption on the left.

maxLength512
trailing_caption: Optional[str]

Label shown top-right.

maxLength512
trailing_subcaption: Optional[str]

Label shown below trailing_caption, on the right.

maxLength512
reactions: Optional[List[Reaction]]

Reactions on this message part

handle: ChatHandle
id: str

Unique identifier for this handle

formatuuid
handle: str

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

joined_at: datetime

When this participant joined the chat

formatdate-time
service: ServiceType

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
is_me: Optional[bool]

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

left_at: Optional[datetime]

When they left (if applicable)

formatdate-time
status: Optional[Literal["active", "left", "removed"]]

Participant status

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

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: Optional[str]

Custom emoji if type is “custom”, null otherwise

sticker: Optional[Sticker]

Sticker attachment details when reaction_type is “sticker”. Null for non-sticker reactions.

file_name: Optional[str]

Filename of the sticker

height: Optional[int]

Sticker image height in pixels

mime_type: Optional[str]

MIME type of the sticker image

url: Optional[str]

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

formaturi
width: Optional[int]

Sticker image width in pixels

type: Literal["imessage_app"]

Indicates this is an iMessage app card part.

url: str

The URL delivered to the iMessage app on tap.

formaturi
fallback_text: Optional[str]

Fallback text for surfaces that cannot render the card.

preferred_service: Optional[ServiceType]

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
read_at: Optional[datetime]

When the message was read

formatdate-time
reply_to: Optional[ReplyTo]

Indicates this message is a threaded reply to another message

message_id: str

The ID of the message to reply to

formatuuid
part_index: Optional[int]

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: Optional[datetime]

When the message was sent

formatdate-time
service: Optional[ServiceType]

Messaging service type

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

Get all messages in a thread

import os
from linq import LinqAPIV3

client = LinqAPIV3(
    api_key=os.environ.get("LINQ_API_V3_API_KEY"),  # This is the default and can be omitted
)
page = client.messages.list_messages_thread(
    message_id="69a37c7d-af4f-4b5e-af42-e28e98ce873a",
)
page = page.messages[0]
print(page.id)
{
  "messages": [
    {
      "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a",
      "chat_id": "94c6bf33-31d9-40e3-a0e9-f94250ecedb9",
      "created_at": "2024-01-15T10:30:00Z",
      "delivery_status": "pending",
      "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"
    }
  ],
  "next_cursor": "eyJpZCI6IjEyMzQ1Njc4OTAiLCJ0cyI6MTYzMDUwMDAwMH0="
}
{
  "error": {
    "status": 401,
    "code": 2004,
    "message": "Unauthorized - missing or invalid authentication token",
    "doc_url": "https://docs.linqapp.com/error/codes/2xxx/2004/"
  },
  "success": false
}
{
  "error": {
    "status": 404,
    "code": 2001,
    "message": "Resource not found",
    "doc_url": "https://docs.linqapp.com/error/codes/2xxx/2001/"
  },
  "success": false
}
{
  "error": {
    "status": 500,
    "code": 3006,
    "message": "Internal server error",
    "doc_url": "https://docs.linqapp.com/error/codes/3xxx/3006/"
  },
  "success": false
}
Returns Examples
{
  "messages": [
    {
      "id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a",
      "chat_id": "94c6bf33-31d9-40e3-a0e9-f94250ecedb9",
      "created_at": "2024-01-15T10:30:00Z",
      "delivery_status": "pending",
      "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"
    }
  ],
  "next_cursor": "eyJpZCI6IjEyMzQ1Njc4OTAiLCJ0cyI6MTYzMDUwMDAwMH0="
}
{
  "error": {
    "status": 401,
    "code": 2004,
    "message": "Unauthorized - missing or invalid authentication token",
    "doc_url": "https://docs.linqapp.com/error/codes/2xxx/2004/"
  },
  "success": false
}
{
  "error": {
    "status": 404,
    "code": 2001,
    "message": "Resource not found",
    "doc_url": "https://docs.linqapp.com/error/codes/2xxx/2001/"
  },
  "success": false
}
{
  "error": {
    "status": 500,
    "code": 3006,
    "message": "Internal server error",
    "doc_url": "https://docs.linqapp.com/error/codes/3xxx/3006/"
  },
  "success": false
}