Skip to content
V2 (Legacy) API ReferenceGet started

Migrating from V2 to V3

Step-by-step guide for upgrading your integration from the Linq V2 API to V3.

V3 is a full redesign — not a patch release. The core change is a shift from synchronous responses to an asynchronous model: the API accepts your request immediately and returns a trace_id, while webhooks tell you what happened. Along the way, the message structure, authentication header, endpoint paths, and error shape all changed.

This guide walks through every breaking change and new capability.

You want to…V2V3
Know when messages actually failmessage.failed webhook
Know exactly when messages are deliveredmessage.delivered webhook
Debug issues quicklytrace_id everywhere
Choose message protocolspreferred_service: iMessage
Send confetti/effects✅ 12 effects
Use custom emoji reactions✅ Any emoji
Send Office docs, ZIP files✅ 18 document types
Know when group names/icons change✅ Group metadata webhooks
Reply to specific messages⚠️ Limited✅ Full threading
Send voice memos✅ Voice memo API

  • Replace X-LINQ-INTEGRATION-TOKEN header with Authorization: Bearer <token>
  • Update all base paths from /api/partner/v2/ to /api/partner/v3/
  • Convert message body: text/attachmentsparts array
  • Parse success boolean and log the trace_id on every response
  • Update webhook handlers for the new payload structure; use event_id for deduplication
  • Switch to the presigned upload flow for attachments
  • Register webhook subscriptions programmatically (see Webhook Subscriptions)

The token value stays the same — only the header name changes.

V2V3
HeaderX-LINQ-INTEGRATION-TOKEN: <token>Authorization: Bearer <token>
Terminal window
# V2
curl -H "X-LINQ-INTEGRATION-TOKEN: $LINQ_API_KEY" ...
# V3
curl -H "Authorization: Bearer $LINQ_API_KEY" ...

See Authentication for full details.


The flat /v2/chat_messages endpoint is gone. V3 nests messages under the chat resource:

OperationV2V3
Send messagePOST /v2/chat_messagesPOST /v3/chats/{chatId}/messages

V2 used top-level text and attachments fields. V3 uses a unified parts array where each part has an explicit type.

V2 request body:

{
"chat_id": "chat-uuid",
"text": "Hello, world!",
"attachments": [{ "url": "https://example.com/image.jpg" }]
}

V3 request body:

{
"message": {
"parts": [
{ "type": "text", "value": "Hello, world!" },
{ "type": "media", "attachment_id": "att-uuid" }
]
}
}

The chat_id moves from the body to the URL path. Message content is wrapped in a message object. Attachments must be pre-uploaded and referenced by attachment_id — see Attachments below.

See Sending Messages and the Send Message API reference for the full schema.


V3 success responses return the resource directly — there is no data wrapper or success field on success.

V2 response:

{
"data": { "chat_message": { "id": "msg-uuid", "text": "Hello" } },
"status": 200
}

V3 success response (send message):

{
"chat_id": "chat-uuid",
"message": {
"id": "msg-uuid",
"delivery_status": "pending",
"service": null,
"parts": [...],
}
}

V3 error response:

{
"success": false,
"error": {
"status": 400,
"code": 1005,
"message": "invalid chatId format: must be a valid UUID"
},
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}

Key changes:

  • success: false and trace_id appear in error responses only — not in the success body
  • trace_id on successful requests is returned in the X-Trace-ID response header; log it for every request
  • service is null on the initial response; it is confirmed via the message.delivered webhook for iMessage and RCS — SMS does not produce a delivery receipt

V2 was synchronous — you waited for a result. V3 is asynchronous:

  1. The API accepts your request and returns a message_id in the body plus a trace_id in the X-Trace-ID response header immediately.
  2. Processing happens in the background.
  3. Webhooks notify you of the outcome: message.sentmessage.delivered or message.failed.

This means silent failures are gone. Any failure will produce a message.failed webhook with error details.

Always log the trace_id — it’s how you correlate an API request with its webhook events and is the first thing support will ask for.

See Webhooks and Debugging for more.


V3 uses structured error responses with numeric codes.

V2 error:

{ "error": "Invalid chat_id", "status": 400 }

V3 error:

{
"success": false,
"error": {
"status": 400,
"code": 1005,
"message": "invalid chatId format: must be a valid UUID"
},
"trace_id": "4bf92f3577b34da6a3ce929d0e0e4736"
}

Update your error handling to read error.code (numeric) rather than parsing the error string. See the Errors guide for the full code reference.


V3 webhook payloads have a new structure with versioning and deduplication support.

V2 payload:

{ "event": "message.sent", "data": { "chat_message": { "id": "msg-uuid" } } }

V3 payload:

{
"api_version": "v3",
"event_type": "message.sent",
"event_id": "550e8400-e29b-41d4-a716-446655440000",
"created_at": "2025-11-23T17:30:00Z",
"trace_id": "abc123def456",
"data": { "message_id": "msg-uuid", "service": "iMessage" }
}

Key differences:

  • event_type replaces event
  • event_id is a stable UUID per event — use it for deduplication; webhooks are delivered at-least-once with up to 10 retries over ~25 minutes
  • trace_id links the event back to the originating API request
  • data shape changed — update your payload destructuring
  • Register and manage subscriptions via the API — see Webhook Subscriptions

New events in V3:

EventDescription
message.deliveredExplicit delivery confirmation
message.failedDelivery failure with error details
chat.group_name_updatedGroup name was changed
chat.group_icon_updatedGroup icon was changed
chat.group_name_update_failedGroup name update failed
chat.group_icon_update_failedGroup icon update failed

See the Webhook Events guide for the full event reference.


V2 accepted a direct URL in the message body. V3 uses a two-step presigned upload flow.

Step 1 — Request an upload URL:

Terminal window
curl -X POST https://api.linqapp.com/api/partner/v3/attachments \
-H "Authorization: Bearer $LINQ_API_KEY" \
-H "Content-Type: application/json" \
-d '{ "filename": "document.pdf", "content_type": "application/pdf", "size_bytes": 1024000 }'

Step 2 — Upload to the presigned S3 URL:

Terminal window
curl -X PUT "https://uploads.linqapp.com/..." \
-H "Content-Type: application/pdf" \
--data-binary @document.pdf

Step 3 — Reference the attachment_id in your message:

{ "message": { "parts": [{ "type": "media", "attachment_id": "att-uuid" }] } }

V3 also expands supported document types from 2 to 18, including Word, Excel, PowerPoint, Pages, Numbers, Keynote, PDF, TXT, RTF, CSV, HTML, ePub, ZIP, and .ics files.

See the Attachments guide for the full list and size limits.


V3 simplifies group creation by combining it with the initial message, and adds explicit participant management endpoints.

V2 creation:

POST /api/partner/v2/chats
{ "phone_numbers": ["+12025550001", "+12025550002"], "display_name": "My Group" }

V3 creation:

POST /api/partner/v3/chats
{
"from": "+12025550100",
"to": ["+12025550001", "+12025550002"],
"message": {
"parts": [{ "type": "text", "value": "Welcome to the group!" }]
}
}

New participant management endpoints:

OperationV3 Path
Add participantsPOST /v3/chats/{chatId}/participants
Remove participantsDELETE /v3/chats/{chatId}/participants
Leave group chatPOST /v3/chats/{chatId}/leave
Update group metadataPUT /v3/chats/{chatId}

See the Group Chats guide for details.


The following V2 features are not yet available in V3.

V2 included a full contacts management API (GET/POST/PUT/PATCH/DELETE /v2/contacts). V3 does not currently have a contacts API. If your integration relies on creating or managing contacts via V2, you will need to continue using V2 for this or handle contact management outside of the Linq API for now.

V2 exposed PUT /v2/phone_numbers/{id} to update a number’s forwarding configuration. This is not yet available in V3.


V2 → V3 path changes:

OperationV2V3
List chatsGET /v2/chatsGET /v3/chats
Create chatPOST /v2/chatsPOST /v3/chats
Get chatGET /v2/chats/{id}GET /v3/chats/{chatId}
Mark as readPUT /v2/chats/{id}/mark_as_readPOST /v3/chats/{chatId}/read
Share contact cardPOST /v2/chats/{id}/share_contactPOST /v3/chats/{chatId}/share_contact_card
Start typingPOST /v2/chats/{id}/start_typingPOST /v3/chats/{chatId}/typing
Stop typingDELETE /v2/chats/{id}/stop_typingDELETE /v3/chats/{chatId}/typing
List messagesGET /v2/chats/{id}/chat_messagesGET /v3/chats/{chatId}/messages
Send messagePOST /v2/chats/{id}/chat_messagesPOST /v3/chats/{chatId}/messages
Get messageGET /v2/chats/{id}/chat_messages/{msgId}GET /v3/messages/{messageId}
Edit messagePOST /v2/chats/{id}/chat_messages/{msgId}/editPATCH /v3/messages/{messageId}
Delete messageDELETE /v2/chats/{id}/chat_messages/{msgId}DELETE /v3/messages/{messageId}
Add/remove reactionPOST /v2/chat_messages/{id}/reactionsPOST /v3/messages/{messageId}/reactions
List phone numbersGET /v2/phone_numbersGET /v3/phone_numbers
Webhook subscriptions/v2/webhook_subscriptions/v3/webhook-subscriptions
iMessage availabilityPOST /v2/i_message_availability/checkPOST /v3/chats/{chatId}/capability

New in V3 (no V2 equivalent):

OperationV3 Path
Update chat metadataPUT /v3/chats/{chatId}
Add participantsPOST /v3/chats/{chatId}/participants
Remove participantsDELETE /v3/chats/{chatId}/participants
Leave group chatPOST /v3/chats/{chatId}/leave
Send voice memoPOST /v3/chats/{chatId}/voicememo
Get threadGET /v3/messages/{messageId}/thread
Upload attachmentPOST /v3/attachments
Get attachment metadataGET /v3/attachments/{attachmentId}

These capabilities have no V2 equivalent.

Protocol selection — Use preferred_service on any message to target a specific channel (iMessage, RCS, or SMS). Useful for iMessage-only features or compliance requirements.

Message effects — Attach iMessage screen effects (confetti, fireworks, lasers, sparkles) or bubble effects (slam, loud, gentle, invisible ink) via the effect object.

Text decorations — Apply bold, italic, strikethrough, underline, and animated styles to character ranges within a text part. iMessage only.

Threaded replies — Reply to a specific message using reply_to: { message_id, part_index }.

Custom reactions — V2 supported the six standard iMessage tapbacks. V3 adds custom emoji reactions on top of those.

Voice memos — Send audio messages as iMessage voice memo bubbles via POST /v3/chats/{chatId}/voicememo.

Participant management — Add and remove participants from existing group chats, and leave a group, via dedicated endpoints.

Rich link previews — Send a link part to render a rich preview card on iMessage and RCS.

Presigned attachment uploads — Upload files via a presigned S3 URL and reference them by attachment_id. Supports 18 document types vs. 2 in V2.