Update an iMessage app card in place
client.messages.updateAppCard(stringmessageID, MessageUpdateAppCardParams { layout, fallback_text, interactive, url } body, RequestOptionsoptions?): MessageUpdateAppCardResponse { chat_id, message }
POST/v3/messages/{messageId}/update
Replaces a previously delivered imessage_app card on the recipient’s screen with new
content, instead of posting a new bubble (like a game move redrawing the board).
The update is delivered as a new message with its own id and delivery lifecycle
(message.sent / message.delivered / message.failed webhooks fire for the new id).
To update the card again, reference the message id returned by this call.
Constraints:
- The referenced message must be an
imessage_appcard sent by you (400otherwise — inbound cards cannot be updated). - The referenced card must already be delivered (
409otherwise — retry after themessage.deliveredwebhook for it). - The app identity (
team_id,bundle_id, name) is inherited from the original card and cannot change; onlyurl,fallback_text, andlayoutare replaced. - iMessage-only, like all app cards.
- Concurrent updates against the same card are not serialized server-side; the last one delivered wins on the recipient’s screen. Serialize updates by always referencing the message id returned by the previous call.
Update an iMessage app card in place
import LinqAPIV3 from '@linqapp/sdk';
const client = new LinqAPIV3({
apiKey: process.env['LINQ_API_V3_API_KEY'], // This is the default and can be omitted
});
const response = await client.messages.updateAppCard('69a37c7d-af4f-4b5e-af42-e28e98ce873a', {
layout: { caption: 'Score: 2 – 1' },
fallback_text: 'Score update',
url: 'https://app.example.com/card?game=7f3a&move=2',
});
console.log(response.chat_id);{
"chat_id": "550e8400-e29b-41d4-a716-446655440000",
"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"
}
}{
"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": 404,
"code": 2001,
"message": "Resource not found",
"doc_url": "https://docs.linqapp.com/error/codes/2xxx/2001/"
},
"success": false
}{
"error": {
"status": 409,
"code": 2013,
"message": "This chat is unavailable",
"doc_url": "https://docs.linqapp.com/error/codes/2xxx/2013/"
},
"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": "550e8400-e29b-41d4-a716-446655440000",
"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"
}
}{
"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": 404,
"code": 2001,
"message": "Resource not found",
"doc_url": "https://docs.linqapp.com/error/codes/2xxx/2001/"
},
"success": false
}{
"error": {
"status": 409,
"code": 2013,
"message": "This chat is unavailable",
"doc_url": "https://docs.linqapp.com/error/codes/2xxx/2013/"
},
"success": false
}{
"error": {
"status": 500,
"code": 3006,
"message": "Internal server error",
"doc_url": "https://docs.linqapp.com/error/codes/3xxx/3006/"
},
"success": false
}