Chats
A Chat is a conversation thread with one or more participants.
To begin a chat, you must create a Chat with at least one recipient handle. Including multiple handles creates a group chat.
When creating a chat, the from field specifies which of your
authorized phone numbers the message originates from. Your authentication token grants
access to one or more phone numbers, but the from field determines the actual sender.
Handle Format:
- Handles can be phone numbers or email addresses
- Phone numbers MUST be in E.164 format (starting with +)
- Phone format:
+[country code][subscriber number] - Example phone:
+12223334444(US),+442071234567(UK),+81312345678(Japan) - Example email:
[email protected] - No spaces, dashes, or parentheses in phone numbers
Create a new chat
List all chats
Get a chat by ID
Mark chat as read
Leave a group chat
ModelsExpand Collapse
Chat object { id, created_at, display_name, 7 more }
Display name for the chat. Defaults to a comma-separated list of recipient handles. Can be updated for group chats.
List of chat participants with full handle details. Always contains at least two handles (your phone number and the other participant).
List of chat participants with full handle details. Always contains at least two handles (your phone number and the other participant).
health_status: object { doc_url, status, updated_at } [BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.
Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.
See the Chat Health guide for what each status means and how to react.
[BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.
Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.
See the Chat Health guide for what each status means and how to react.
status: "HEALTHY" or "AT_RISK" or "CRITICAL" or "OPTED_OUT"Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.
OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT.
The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop
does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any
casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as
soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back
in immediately — a reply in any conversation with you counts, the same way the block does.
OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so
a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status.
Group threads are never marked and are never blocked.
Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code
2024) before the message is queued, across every chat and every line on your account. Nothing is
delivered, including a final courtesy message — to send one, set override_optout: true on that single
request.
Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.
OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT.
The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop
does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any
casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as
soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back
in immediately — a reply in any conversation with you counts, the same way the block does.
OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so
a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status.
Group threads are never marked and are never blocked.
Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code
2024) before the message is queued, across every chat and every line on your account. Nothing is
delivered, including a final courtesy message — to send one, set override_optout: true on that single
request.
DEPRECATED: This field is deprecated and will be removed in a future API version.
URL of the group chat icon. Only set for group chats that have an icon; null otherwise.
MediaPart object { type, attachment_id, url }
Reference to a file pre-uploaded via POST /v3/attachments (optional).
The file is already stored, so sends using this ID skip the download step —
useful when sending the same file to many recipients.
Either url or attachment_id must be provided, but not both.
Any publicly accessible HTTPS URL to the media file. The server downloads and sends the file automatically — no pre-upload step required.
Size limit: 10MB maximum for URL-based downloads. For larger files (up to 100MB),
use the pre-upload flow: POST /v3/attachments to get a presigned URL, upload directly,
then reference by attachment_id.
Requirements:
- URL must use HTTPS
- File content must be a supported format (the server validates the actual file content)
Supported formats:
- Images: .jpg, .jpeg, .png, .gif, .heic, .heif, .tif, .tiff, .bmp
- Videos: .mp4, .mov, .m4v, .mpeg, .mpg, .3gp
- Audio: .m4a, .mp3, .aac, .caf, .wav, .aiff, .amr
- Documents: .pdf, .txt, .rtf, .csv, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .pages, .numbers, .key, .epub, .zip, .html, .htm
- Contact & Calendar: .vcf, .ics
Tip: Audio sent here appears as a regular file attachment.
For repeated sends of the same file, use attachment_id to avoid redundant downloads.
Either url or attachment_id must be provided, but not both.
MessageContent object { parts, idempotency_key, reply_to } Message content container. Groups all message-related fields together,
separating the “what” (message content) from the “where” (routing fields like from/to).
Message content container. Groups all message-related fields together, separating the “what” (message content) from the “where” (routing fields like from/to).
parts: array of TextPart { type, value } or MediaPart { type, attachment_id, url } or LinkPart { type, value } The message’s one part: text, media, or link. An RCS message carries exactly
one part; send text and media as separate messages.
Rich Link Previews:
- Use a
link part to send a URL with a rich preview card
- A URL inside a
text part renders a preview too
Supported Media:
- Images: .jpg, .jpeg, .png, .gif, .heic, .heif, .tif, .tiff, .bmp
- Videos: .mp4, .mov, .m4v, .mpeg, .mpg, .3gp
- Audio: .m4a, .mp3, .aac, .caf, .wav, .aiff, .amr
- Documents: .pdf, .txt, .rtf, .csv, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .pages, .numbers, .key, .epub, .zip, .html, .htm
- Contact & Calendar: .vcf, .ics
Audio:
- Audio files (.m4a, .mp3, .aac, .caf, .wav, .aiff, .amr) are fully supported as media parts
Validation Rules:
- Exactly one part per message.
The message’s one part: text, media, or link. An RCS message carries exactly one part; send text and media as separate messages.
Rich Link Previews:
- Use a
linkpart to send a URL with a rich preview card - A URL inside a
textpart renders a preview too
Supported Media:
- Images: .jpg, .jpeg, .png, .gif, .heic, .heif, .tif, .tiff, .bmp
- Videos: .mp4, .mov, .m4v, .mpeg, .mpg, .3gp
- Audio: .m4a, .mp3, .aac, .caf, .wav, .aiff, .amr
- Documents: .pdf, .txt, .rtf, .csv, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .pages, .numbers, .key, .epub, .zip, .html, .htm
- Contact & Calendar: .vcf, .ics
Audio:
- Audio files (.m4a, .mp3, .aac, .caf, .wav, .aiff, .amr) are fully supported as media parts
Validation Rules:
- Exactly one part per message.
MediaPart object { type, attachment_id, url }
Reference to a file pre-uploaded via POST /v3/attachments (optional).
The file is already stored, so sends using this ID skip the download step —
useful when sending the same file to many recipients.
Either url or attachment_id must be provided, but not both.
Any publicly accessible HTTPS URL to the media file. The server downloads and sends the file automatically — no pre-upload step required.
Size limit: 10MB maximum for URL-based downloads. For larger files (up to 100MB),
use the pre-upload flow: POST /v3/attachments to get a presigned URL, upload directly,
then reference by attachment_id.
Requirements:
- URL must use HTTPS
- File content must be a supported format (the server validates the actual file content)
Supported formats:
- Images: .jpg, .jpeg, .png, .gif, .heic, .heif, .tif, .tiff, .bmp
- Videos: .mp4, .mov, .m4v, .mpeg, .mpg, .3gp
- Audio: .m4a, .mp3, .aac, .caf, .wav, .aiff, .amr
- Documents: .pdf, .txt, .rtf, .csv, .doc, .docx, .xls, .xlsx, .ppt, .pptx, .pages, .numbers, .key, .epub, .zip, .html, .htm
- Contact & Calendar: .vcf, .ics
Tip: Audio sent here appears as a regular file attachment.
For repeated sends of the same file, use attachment_id to avoid redundant downloads.
Either url or attachment_id must be provided, but not both.
Optional idempotency key for this message. Use this to prevent duplicate sends of the same message. Reusing a key whose message was deleted returns 404; the message is never resent.
ChatCreateResponse object { chat } Response for creating a new chat with an initial message
Response for creating a new chat with an initial message
chat: object { id, display_name, handles, 4 more }
Display name for the chat. Defaults to a comma-separated list of recipient handles. Can be updated for group chats.
List of participants in the chat. Always contains at least two handles (your phone number and the other participant).
List of participants in the chat. Always contains at least two handles (your phone number and the other participant).
health_status: object { doc_url, status, updated_at } [BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.
Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.
See the Chat Health guide for what each status means and how to react.
[BETA] Current health for a chat. Always present — chats start at HEALTHY and may shift based on engagement and delivery signals on the conversation. Many AT_RISK or CRITICAL chats on a single line increase the risk of line flagging.
Switch on status to surface chat and line health in your UI — the enum is the long-term contract. Each status carries a doc_url that deep-links to the relevant section of the Chat Health guide. To gate a send, act on the response rather than the status: a 403 is the authoritative answer.
See the Chat Health guide for what each status means and how to react.
status: "HEALTHY" or "AT_RISK" or "CRITICAL" or "OPTED_OUT"Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.
OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT.
The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop
does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any
casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as
soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back
in immediately — a reply in any conversation with you counts, the same way the block does.
OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so
a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status.
Group threads are never marked and are never blocked.
Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code
2024) before the message is queued, across every chat and every line on your account. Nothing is
delivered, including a final courtesy message — to send one, set override_optout: true on that single
request.
Current health bucket for the chat. See the Chat Health guide for what each value means and how to react. doc_url deep-links to the relevant section.
OPTED_OUT — the recipient sent STOP, UNSUBSCRIBE, OPTOUT, CANCEL, END, or QUIT.
The keyword must be the whole trimmed message, never part of a longer one: STOP counts, please stop
does not. Most keywords must match exactly, including case. OPT OUT is the exception — it matches in any
casing, with or without the space or a hyphen, so opt out, Opt-Out and optout all count. It clears as
soon as they reply again: any later message from them that is not itself an opt-out keyword opts them back
in immediately — a reply in any conversation with you counts, the same way the block does.
OPTED_OUT marks only the conversation the keyword arrived in. The block below is wider than the mark, so
a conversation still reading HEALTHY can be blocked as well — gate on the 403, not on the status.
Group threads are never marked and are never blocked.
Linq enforces this: while a recipient is opted out, every send to them is rejected with 403 (error code
2024) before the message is queued, across every chat and every line on your account. Nothing is
delivered, including a final courtesy message — to send one, set override_optout: true on that single
request.
A message that was sent (used in CreateChat and SendMessage responses)
A message that was sent (used in CreateChat and SendMessage responses)
DEPRECATED: Use delivery_status == "read" instead. Whether the message has been read.
parts: array of TextPartResponse { reactions, type, value } or MediaPartResponse { id, filename, mime_type, 4 more } or LinkPartResponse { reactions, type, value } Message parts in order (text, media, and link)
Message parts in order (text, media, and link)
TextPartResponse object { reactions, type, value } A text message part
A text message part
Reactions on this message part
Reactions on this message part
MediaPartResponse object { id, filename, mime_type, 4 more } A media attachment part
A media attachment part
Reactions on this message part
Reactions on this message part
LinkPartResponse object { reactions, type, value } A rich link preview part
A rich link preview part
Reactions on this message part
Reactions on this message part
The sender of this message as a full handle object
The sender of this message as a full handle object
ChatsParticipants
A Chat is a conversation thread with one or more participants.
To begin a chat, you must create a Chat with at least one recipient handle. Including multiple handles creates a group chat.
When creating a chat, the from field specifies which of your
authorized phone numbers the message originates from. Your authentication token grants
access to one or more phone numbers, but the from field determines the actual sender.
Handle Format:
- Handles can be phone numbers or email addresses
- Phone numbers MUST be in E.164 format (starting with +)
- Phone format:
+[country code][subscriber number] - Example phone:
+12223334444(US),+442071234567(UK),+81312345678(Japan) - Example email:
[email protected] - No spaces, dashes, or parentheses in phone numbers
Add a participant to a chat
Remove a participant from a chat
ChatsTyping
A Chat is a conversation thread with one or more participants.
To begin a chat, you must create a Chat with at least one recipient handle. Including multiple handles creates a group chat.
When creating a chat, the from field specifies which of your
authorized phone numbers the message originates from. Your authentication token grants
access to one or more phone numbers, but the from field determines the actual sender.
Handle Format:
- Handles can be phone numbers or email addresses
- Phone numbers MUST be in E.164 format (starting with +)
- Phone format:
+[country code][subscriber number] - Example phone:
+12223334444(US),+442071234567(UK),+81312345678(Japan) - Example email:
[email protected] - No spaces, dashes, or parentheses in phone numbers
Start typing indicator
Stop typing indicator
ChatsMessages
Messages are individual communications within a chat thread.
Messages can include text, media attachments, rich link previews, and reactions. All messages are associated with a specific chat and sent from a phone number you own.
Messages support delivery status tracking and read receipts.
Rich Link Previews
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 URL inside a text
part renders a preview too.
Limitations:
- A message carries exactly one part, so a link is never combined with text or media.
- Maximum URL length: 2,048 characters.
Send a message to an existing chat
Get messages from a chat
ModelsExpand Collapse
SentMessage object { id, created_at, delivery_status, 7 more } A message that was sent (used in CreateChat and SendMessage responses)
A message that was sent (used in CreateChat and SendMessage responses)
DEPRECATED: Use delivery_status == "read" instead. Whether the message has been read.
parts: array of TextPartResponse { reactions, type, value } or MediaPartResponse { id, filename, mime_type, 4 more } or LinkPartResponse { reactions, type, value } Message parts in order (text, media, and link)
Message parts in order (text, media, and link)
TextPartResponse object { reactions, type, value } A text message part
A text message part
Reactions on this message part
Reactions on this message part
MediaPartResponse object { id, filename, mime_type, 4 more } A media attachment part
A media attachment part
Reactions on this message part
Reactions on this message part
LinkPartResponse object { reactions, type, value } A rich link preview part
A rich link preview part
Reactions on this message part
Reactions on this message part
The sender of this message as a full handle object
The sender of this message as a full handle object
MessageSendResponse object { chat_id, message } Response for sending a message to a chat
Response for sending a message to a chat
A message that was sent (used in CreateChat and SendMessage responses)
A message that was sent (used in CreateChat and SendMessage responses)
DEPRECATED: Use delivery_status == "read" instead. Whether the message has been read.
parts: array of TextPartResponse { reactions, type, value } or MediaPartResponse { id, filename, mime_type, 4 more } or LinkPartResponse { reactions, type, value } Message parts in order (text, media, and link)
Message parts in order (text, media, and link)
TextPartResponse object { reactions, type, value } A text message part
A text message part
Reactions on this message part
Reactions on this message part
MediaPartResponse object { id, filename, mime_type, 4 more } A media attachment part
A media attachment part
Reactions on this message part
Reactions on this message part
LinkPartResponse object { reactions, type, value } A rich link preview part
A rich link preview part
Reactions on this message part
Reactions on this message part
The sender of this message as a full handle object
The sender of this message as a full handle object