Skip to main content
POST
cURL
Add a message to a ticket’s thread. This is the same conversation thread agents see in the ticket detail view — public replies and internal notes both live here.
If authorType is user, the message is automatically attributed to the user who owns the API key — you cannot pass a different authorUserId. For ai_agent, you must pass the matching authorAgentId. For customer, pass authorCustomerId when you have it, but it is not required yet.

Path parameters

string
required
Ticket UUID. Find it from Get ticket or Search tickets.

Request body

The ticket ticketId comes from the URL path — do not include it in the body.
string
required
Rich HTML body shown in the thread.
string
required
Plain-text version of the body, used for search, SMS, and accessibility.
string
required
Who this message is from: user, customer, system, or ai_agent.
  • user — attributed to the API key’s owning user automatically. Do not pass authorUserId.
  • customer — optionally pair with authorCustomerId (see note below).
  • ai_agent — requires authorAgentId.
  • system — no author reference needed; use for automated/system-generated entries.
string
Customer UUID. Recommended when authorType is customer, but not enforced yet — pass it when you have it so the thread shows the right customer.
string
Voice/AI agent UUID. Required when authorType is ai_agent.
boolean
default:"false"
Set to true to add an internal note that is never sent to the customer. false posts a customer-visible reply.
string
Channel this message is associated with, e.g. manual, api. See Create ticket for the full list of sources.
string
Groups internal-note side threads. Omit unless you are replying within a specific side thread.
string
Provider message ID, used to deduplicate messages ingested from an external channel.
object
Email threading headers (messageId, inReplyTo, references, fromAddress, toAddresses, ccAddresses, bccAddresses, subject). Only relevant for email-sourced messages.
object
Provider-specific extras (e.g. Slack or WhatsApp metadata) that do not have a dedicated field.
string
ISO 8601 timestamp for a delayed send. Pair with status: "scheduled".
string
ISO 8601 timestamp the message was delivered. Defaults to the current time if omitted.
string
default:"sent"
One of draft, scheduled, sent, or failed.
Posting a public reply (isPrivate: false) updates the ticket’s lastAgentActivityAt, and sets firstResponseAt the first time it happens. This endpoint does not trigger any webhook.
The request fails with a validation error if authorType is ai_agent without authorAgentId. authorType: "customer" without authorCustomerId is currently allowed while customer matching on the tickets platform matures — this will likely become required in the future.

Authorizations

Authorization
string
header
required

Bearer authentication header of the form Bearer <token>, where <token> is your auth token.

Headers

x-api-key
string
required
Minimum string length: 1
x-workspace-slug
string
required
x-workspace-id
string<uuid>
required
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$

Path Parameters

ticketId
string<uuid>
required
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$

Body

application/json
bodyHtml
string
required
bodyPlain
string
required
authorType
enum<string>
required
Available options:
user,
customer,
system,
ai_agent
threadId
string<uuid> | null
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
authorCustomerId
string<uuid> | null
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
authorAgentId
string<uuid> | null
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
isPrivate
boolean
default:false
source
enum<string> | null
Available options:
email,
chat_widget,
voice,
whatsapp,
sms,
customer_portal,
form,
manual,
api,
slack,
microsoft_teams,
instagram,
discord,
telegram
externalMessageId
string | null
emailInfo
channelMetadata
scheduledAt
string | null
sentAt
string | null
status
enum<string>
Available options:
draft,
scheduled,
sent,
failed

Response

Successful response

ticketId
string<uuid>
required
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
threadId
string<uuid> | null
required
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
bodyHtml
string
required
bodyPlain
string
required
authorType
enum<string>
required
Available options:
user,
customer,
system,
ai_agent
authorUserId
string<uuid> | null
required
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
authorCustomerId
string<uuid> | null
required
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
authorAgentId
string<uuid> | null
required
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
isPrivate
boolean
required
source
enum<string> | null
required
Available options:
email,
chat_widget,
voice,
whatsapp,
sms,
customer_portal,
form,
manual,
api,
slack,
microsoft_teams,
instagram,
discord,
telegram
externalMessageId
string | null
required
emailInfo
required
channelMetadata
required
scheduledAt
string | null
required
sentAt
string | null
required
status
enum<string>
required
Available options:
draft,
scheduled,
sent,
failed
id
string<uuid>
required
Pattern: ^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$
createdAt
string
required
updatedAt
string
required