Skip to main content
Sends a follow-up in an existing chat. This is a chat-scoped route: {id} is the chat_id, not a message_id.
The body is wrapped in message. Top-level parts will be rejected.
For group chats, create the group with a text-only POST /api/v1/chats call first. Send media and rich links through this follow-up endpoint after the group chat exists.

Request

curl -X POST https://console.trychert.com/api/v1/chats/$CHAT_ID/messages \
  -H "Authorization: Bearer $CHERT_SIGNING_SECRET" \
  -H "Content-Type: application/json" \
  -d '{
    "message": {
      "parts": [{ "type": "text", "value": "How about 3pm PT?" }],
      "idempotency_key": "followup-2026-05-01-002"
    }
  }'

Send media

Upload first, then reference the attachment_id.
{
  "message": {
    "parts": [
      { "type": "text", "value": "See attached." },
      { "type": "media", "attachment_id": "9f3b27a8c14d4a6f8e2b91d4c5e6f7a8" }
    ]
  }
}
The rich_link part shape is the same on every Chert sender line. The rich link is rendered as its own preview bubble.
{
  "message": {
    "parts": [
      { "type": "text", "value": "Leaving this here." },
      { "type": "rich_link", "url": "https://example.com/demo" }
    ]
  }
}
Optional fields: title, summary, image_url, icon_url. This is the recommended shape for review-request messages that include a personalized image and a previewed URL.
{
  "message": {
    "parts": [
      { "type": "media", "attachment_id": "9f3b27a8c14d4a6f8e2b91d4c5e6f7a8" },
      { "type": "text", "value": "Hi Marcus, this is Todd from Texas Prime Plumbing. I would really appreciate a Google review." },
      { "type": "rich_link", "url": "https://search.google.com/local/writereview?placeid=..." }
    ]
  }
}

Response

{
  "message": {
    "id": "46eb1003c8b54b7ea8f1c2b03e9a7d12",
    "chat_id": "0f2d3c1a-8b4e-4f6a-90d2-1a3b4c5d6e7f",
    "parts": [{ "type": "text", "value": "How about 3pm PT?" }],
    "status": "sent",
    "direction": "outbound",
    "created_at": "2026-05-01T14:30:00Z",
    "delivered_at": null,
    "read_at": null,
    "service": "imessage"
  }
}
The returned message.id is the id to pass to message-scoped actions such as POST /api/v1/messages/{id}/react.

Fields

FieldRequiredNotes
Path idYesThe chat.id returned by POST /api/v1/chats. Do not pass message.id or convo_id here.
message.partsYesArray of text, media, and rich_link parts. Text parts use value; media parts reference an uploaded attachment_id; rich-link parts use { "type": "rich_link", "url": "https://..." }.
message.idempotency_keyNoSafe retry key scoped to the tenant.

See also