Sending Messages
How to send text, media, and rich messages with the Linq API.
The Linq API lets you send messages containing text, media, or a mix of both across iMessage, RCS, and SMS.
Starting a conversation
Section titled “Starting a conversation”To message a new recipient, create a chat with an initial message. The API creates the conversation and sends the message in a single request:
curl -X POST https://api.linqapp.com/api/partner/v3/chats \ -H "Authorization: Bearer $LINQ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "from": "+12223334444", "to": ["+15556667777"], "message": { "parts": [ { "type": "text", "value": "Hello from Linq!" } ] } }'const chat = await client.chats.create({ from: '+12223334444', to: ['+15556667777'], message: { parts: [{ type: 'text', value: 'Hello from Linq!' }], },});chat = client.chats.create( from_="+12223334444", to=["+15556667777"], message={ "parts": [{"type": "text", "value": "Hello from Linq!"}] },)A few constraints on this request:
frommust be a phone number assigned to your account.toaccepts an array — one recipient for a direct message, multiple for a group chat.- The first outbound message must not contain links.
linkparts and text parts containing URLs are rejected onPOST /v3/chats— send the initial message without links, then follow up with a link preview using the returned chat ID.
See the Create Chat endpoint for the full request schema.
Sending to an existing chat
Section titled “Sending to an existing chat”Once you have a chat ID, post follow-up messages directly to it. The request body is a message object with a parts array — see the Send Message API reference for the full schema and language-specific examples.
Message parts
Section titled “Message parts”Messages use a parts array where each part is text, media, or link. You can mix text and media in a single message; link parts must be sent on their own.
Text part:
{ "type": "text", "value": "Hello!" }Media part (direct URL):
{ "type": "media", "url": "https://example.com/photo.jpg"}Media part (pre-uploaded attachment):
{ "type": "media", "attachment_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890"}Link part (rich link preview):
{ "type": "link", "value": "https://linqapp.com"}Mixed message (text + image) — full request body:
{ "message": { "parts": [ { "type": "text", "value": "Check out this photo!" }, { "type": "media", "url": "https://example.com/photo.jpg" } ] }}Note: Media parts reference the file by
urlorattachment_id. MIME type is inferred server-side — you do not need to pass amime_typefield.
Limits:
- Up to 100 parts per message
- Up to 40 public-URL media parts per message (pre-uploaded attachments are exempt)
- Text
valuemax length: 10,000 characters - Link
value(URL) max length: 2,048 characters - Link parts must be the only part in a message — they render as a rich preview on iMessage and RCS
- Consecutive text parts are not allowed — separate them with media or send as individual messages
See Attachments for details on sending media files.
Text decorations
Section titled “Text decorations”Apply inline styles and animations to character ranges within a text part using the text_decorations array. Each decoration specifies a range: [start, end) (inclusive–exclusive, measured in UTF-16 code units) and exactly one of style or animation. Decorations are iMessage-only and ignored on RCS and SMS (see Protocol Selection).
{ "type": "text", "value": "Hello world", "text_decorations": [ { "range": [0, 5], "style": "bold" }, { "range": [6, 11], "animation": "shake" } ]}Styles: bold, italic, strikethrough, underline
Animations: big, small, shake, nod, explode, ripple, bloom, jitter
Style ranges may overlap (e.g. bold + italic on the same characters), but animation ranges must not overlap with other animations or styles.
Replying to messages
Section titled “Replying to messages”Thread messages by referencing a specific message ID:
curl -X POST https://api.linqapp.com/api/partner/v3/chats/{chat_id}/messages \ -H "Authorization: Bearer $LINQ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "message": { "parts": [ { "type": "text", "value": "Great point!" } ], "reply_to": { "message_id": "6ba7b810-9dad-11d1-80b4-00c04fd430c8", "part_index": 0 } } }'The part_index field is optional — use it to reply to a specific part of a multipart message (0-indexed). To walk a thread after building it, see Message Details → Get thread messages.
Message effects
Section titled “Message effects”Add iMessage screen or bubble effects (confetti, fireworks, slam, invisible ink, etc.) by including an effect object inside message. iMessage only — silently ignored on RCS and SMS. See Message Effects for the full list and an example.
Protocol selection
Section titled “Protocol selection”Force a specific delivery protocol with preferred_service (iMessage, RCS, or SMS) inside message. If omitted, the API picks the best available. See Protocol Selection for behavior and tradeoffs.
Idempotency
Section titled “Idempotency”Include an idempotency_key field inside the message object to prevent duplicate sends on retries. It goes inside the message body, not as an HTTP header. Maximum length is 255 characters.
curl -X POST https://api.linqapp.com/api/partner/v3/chats/{chat_id}/messages \ -H "Authorization: Bearer $LINQ_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "message": { "parts": [{ "type": "text", "value": "This won'\''t be sent twice" }], "idempotency_key": "unique-request-id-123" } }'The same applies when creating a chat (POST /v3/chats) — the key goes inside the nested message object:
{ "from": "+12223334444", "to": ["+15556667777"], "message": { "parts": [{ "type": "text", "value": "Hello" }], "idempotency_key": "unique-request-id-123" }}If a message with the same key has already been processed, the API returns the original response instead of sending again.
Tip: Use UUIDs or other globally unique values as idempotency keys, and always set one in production to handle network retries safely. The official SDKs accept the key via a method option.
Editing messages
Section titled “Editing messages”Edit a single text part of a previously sent message by passing part_index (0-based) and the new text. Only text parts are editable. iMessage only — listen for the message.edited webhook to confirm the edit was applied. Editable up to 5 times within 15 minutes of the original send. See the Edit Message API reference.
Deleting messages
Section titled “Deleting messages”Delete removes a message from Linq’s records but does not unsend it — recipients still see the message on their device. See the Delete Message API reference.