Send a message (auto-selected from-number)
Send a message to one or more recipients without supplying a from
number. Linq resolves both the sending line and the target chat for you,
then returns exactly which line was used, which chat the message landed in,
whether a new chat was created, and every resulting message id.
This fuses “create chat” and “send message” behind a single
message-centric resource. Provide only the recipients (to) and the
message; the platform decides the rest.
How the from-number and chat are chosen
- Reuse — if a chat with exactly these recipients already exists on a
line that can still send, the message is sent into that chat on its
existing line (
from_selection.reason = reused_active_chat). The most-recently-active such chat wins; chats stranded on flagged lines (e.g. by an earlier failover) are skipped. - New — if no such chat exists, a new chat is created on the best
available line (
from_selection.reason = new_best_number). - Failover — if matching chats exist but none is on a line that can
send, a new chat is created on a fresh best line and the flagged chat
is abandoned (
from_selection.reason = failover_flagged,previous_chat_idset). If you supplycontinuation_message, that text is sent as the single message INSTEAD ofmessage(useful as a fresh-number-appropriate opener). Exactly one message is sent either way.
Recipients (to) are an order-independent set: a single handle is a direct
chat, multiple handles a group chat.
Excluding lines
exclude_from keeps specific lines out of this send’s line pick. It
only affects picking a line for a new chat — an existing chat is always
reused on its own line, preferring a chat on a non-excluded line when the
recipients have more than one. An exclusion never abandons a live chat or
moves it to a new number, so if the only chat these recipients have is on
an excluded line, that chat is still used. from tells you the line that
was actually used.
Differences from POST /v3/chats
- The first message may contain a link (including for a newly created chat). Note: sending a link as the very first message on a freshly selected line can elevate that line’s flagging risk — it is allowed, not recommended.
- Voice memos are not supported here. To send an iMessage voice-memo
bubble, use
POST /v3/chats/{chatId}/voicememowith a known chat id.
Service preference, effects, decorations
Set message.preferred_service (iMessage | RCS | SMS), message.effect,
and per-part text_decorations exactly as on the other send endpoints.
Always responds 202 Accepted — chat creation is incidental to the send.
Body ParametersJSON
Recipient handles (E.164 phone numbers or email addresses). One handle is a direct chat; multiple handles a group chat. Order-independent — the set identifies the chat.
Lines (E.164) not to pick for this send. Applies for this request only — nothing is remembered between calls.
Exclusion only affects picking a line for a new chat. If to
already has a chat, that chat is reused on its own line, and a chat on
a non-excluded line is preferred when there is more than one. If the
only chat these recipients have is on an excluded line, it is still
reused — an exclusion never abandons a live chat or moves it to a new
number. Check from in the response to see the line that was actually
used.
Numbers that are not your lines are ignored. Every entry must be
E.164 — a value like 4155551234 is rejected rather than silently
skipped. Excluding every one of your available lines returns 400 when
a line has to be picked.
Returns
Send a message (auto-selected from-number)
curl https://api.linqapp.com/api/partner/v3/messages \
-H 'Content-Type: application/json' \
-H "Authorization: Bearer $LINQ_API_V3_API_KEY" \
-d '{
"message": {
"parts": [
{
"type": "text",
"value": "Hi! Thanks for reaching out — how can we help?"
}
]
},
"to": [
"+14155559876"
],
"exclude_from": [
"+12052535597"
]
}'{
"chat_id": "94c6bf33-31d9-40e3-a0e9-f94250ecedb9",
"created_new_chat": false,
"from": "+12052535597",
"from_selection": {
"reason": "reused_active_chat",
"reused_existing_chat": true
},
"handles": [
{
"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"
}
],
"is_group": false,
"message": {
"id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a",
"created_at": "2025-10-23T13:07:55.019-05:00",
"delivery_status": "pending",
"is_read": false,
"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"
}
]
}
],
"sent_at": null,
"delivered_at": null,
"effect": {
"name": "confetti",
"type": "screen"
},
"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"
},
"preferred_service": "iMessage",
"reply_to": {
"message_id": "550e8400-e29b-41d4-a716-446655440000",
"part_index": 0
},
"service": "iMessage"
},
"service": "iMessage",
"previous_chat_id": null
}{
"error": {
"status": 400,
"code": 1002,
"message": "Phone number must be in E.164 format",
"doc_url": "https://docs.linqapp.com/error/codes/1xxx/1002/"
},
"success": false
}{
"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": 403,
"code": 2005,
"message": "Access denied - insufficient permissions for this resource",
"doc_url": "https://docs.linqapp.com/error/codes/2xxx/2005/"
},
"success": false
}{
"error": {
"status": 409,
"code": 2015,
"message": "no eligible sending line available",
"doc_url": "https://docs.linqapp.com/error/codes/2xxx/2015/"
},
"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
{
"chat_id": "94c6bf33-31d9-40e3-a0e9-f94250ecedb9",
"created_new_chat": false,
"from": "+12052535597",
"from_selection": {
"reason": "reused_active_chat",
"reused_existing_chat": true
},
"handles": [
{
"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"
}
],
"is_group": false,
"message": {
"id": "69a37c7d-af4f-4b5e-af42-e28e98ce873a",
"created_at": "2025-10-23T13:07:55.019-05:00",
"delivery_status": "pending",
"is_read": false,
"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"
}
]
}
],
"sent_at": null,
"delivered_at": null,
"effect": {
"name": "confetti",
"type": "screen"
},
"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"
},
"preferred_service": "iMessage",
"reply_to": {
"message_id": "550e8400-e29b-41d4-a716-446655440000",
"part_index": 0
},
"service": "iMessage"
},
"service": "iMessage",
"previous_chat_id": null
}{
"error": {
"status": 400,
"code": 1002,
"message": "Phone number must be in E.164 format",
"doc_url": "https://docs.linqapp.com/error/codes/1xxx/1002/"
},
"success": false
}{
"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": 403,
"code": 2005,
"message": "Access denied - insufficient permissions for this resource",
"doc_url": "https://docs.linqapp.com/error/codes/2xxx/2005/"
},
"success": false
}{
"error": {
"status": 409,
"code": 2015,
"message": "no eligible sending line available",
"doc_url": "https://docs.linqapp.com/error/codes/2xxx/2015/"
},
"success": false
}{
"error": {
"status": 500,
"code": 3006,
"message": "Internal server error",
"doc_url": "https://docs.linqapp.com/error/codes/3xxx/3006/"
},
"success": false
}