Skip to content
Get started

Messages

Messages are individual communications within a chat thread.

Messages can include text, media attachments, rich link previews, special effects (like confetti or fireworks), and reactions. All messages are associated with a specific chat and sent from a phone number you own.

Messages support delivery status tracking, read receipts, and editing capabilities.

Send a URL as a link part to deliver it with a rich preview card showing the page’s title, description, and image (when available). A link part must be the only part in the message — it cannot be combined with text or media parts. To send a URL without a preview card, include it in a text part instead.

Limitations:

  • A link part cannot be combined with other parts in the same message.
  • Maximum URL length: 2,048 characters.
Send a message to an existing chat
client.chats.messages.send(stringchatID, MessageSendParams { message } body, RequestOptionsoptions?): MessageSendResponse { chat_id, message }
POST/v3/chats/{chatId}/messages
Get messages from a chat
client.chats.messages.list(stringchatID, MessageListParams { cursor, limit } query?, RequestOptionsoptions?): ListMessagesPagination<Message { id, chat_id, created_at, 15 more } >
GET/v3/chats/{chatId}/messages
ModelsExpand Collapse
SentMessage { id, created_at, delivery_status, 9 more }

A message that was sent (used in CreateChat and SendMessage responses)

id: string

Message identifier (UUID)

formatuuid
created_at: string

When the message was created

formatdate-time
delivery_status: "pending" | "queued" | "sent" | 4 more

Current delivery status of a message

One of the following:
"pending"
"queued"
"sent"
"delivered"
"received"
"read"
"failed"
Deprecatedis_read: boolean

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

parts: Array<TextPartResponse { reactions, type, value, text_decorations } | MediaPartResponse { id, filename, mime_type, 4 more } | LinkPartResponse { reactions, type, value } | iMessageAppPartResponse { app, layout, reactions, 3 more } >

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

iMessageAppPartResponse { app, layout, reactions, 3 more }

An iMessage app card part.

app: App { bundle_id, name, team_id, app_store_id }

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

bundle_id: string

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

minLength1
maxLength255
name: string

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

minLength1
maxLength64
team_id: string

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

app_store_id?: number

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: Layout { caption, subcaption, trailing_caption, trailing_subcaption }

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?: string

Primary label, top-left and bold.

maxLength512
subcaption?: string

Secondary label, below caption on the left.

maxLength512
trailing_caption?: string

Label shown top-right.

maxLength512
trailing_subcaption?: string

Label shown below trailing_caption, on the right.

maxLength512
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: "imessage_app"

Indicates this is an iMessage app card part.

url: string

The URL delivered to the iMessage app on tap.

formaturi
fallback_text?: string | null

Fallback text for surfaces that cannot render the card.

sent_at: string | null

When the message was actually sent (null if still queued)

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"
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"
preferred_service?: ServiceType | null

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
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
service?: ServiceType | null

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
MessageSendResponse { chat_id, message }

Response for sending a message to a chat

chat_id: string

Unique identifier of the chat this message was sent to

formatuuid
message: SentMessage { id, created_at, delivery_status, 9 more }

A message that was sent (used in CreateChat and SendMessage responses)

id: string

Message identifier (UUID)

formatuuid
created_at: string

When the message was created

formatdate-time
delivery_status: "pending" | "queued" | "sent" | 4 more

Current delivery status of a message

One of the following:
"pending"
"queued"
"sent"
"delivered"
"received"
"read"
"failed"
Deprecatedis_read: boolean

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

parts: Array<TextPartResponse { reactions, type, value, text_decorations } | MediaPartResponse { id, filename, mime_type, 4 more } | LinkPartResponse { reactions, type, value } | iMessageAppPartResponse { app, layout, reactions, 3 more } >

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

iMessageAppPartResponse { app, layout, reactions, 3 more }

An iMessage app card part.

app: App { bundle_id, name, team_id, app_store_id }

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

bundle_id: string

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

minLength1
maxLength255
name: string

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

minLength1
maxLength64
team_id: string

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

app_store_id?: number

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: Layout { caption, subcaption, trailing_caption, trailing_subcaption }

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?: string

Primary label, top-left and bold.

maxLength512
subcaption?: string

Secondary label, below caption on the left.

maxLength512
trailing_caption?: string

Label shown top-right.

maxLength512
trailing_subcaption?: string

Label shown below trailing_caption, on the right.

maxLength512
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: "imessage_app"

Indicates this is an iMessage app card part.

url: string

The URL delivered to the iMessage app on tap.

formaturi
fallback_text?: string | null

Fallback text for surfaces that cannot render the card.

sent_at: string | null

When the message was actually sent (null if still queued)

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"
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"
preferred_service?: ServiceType | null

Messaging service type

One of the following:
"iMessage"
"SMS"
"RCS"
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
service?: ServiceType | null

Messaging service type

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