ticketNumber path parameter is that per-agent number, not a global id. A ticket’s channel records where it originated, such as email, the chat widget, or WhatsApp. Tickets created through this API always have channel: "api".
Statuses
Each ticket has a status, and each status belongs to one of six fixed categories:new, on_you, on_customer, on_hold, closed, cancelled. The statuses themselves are configured per agent in the dashboard; every category has exactly one default status.
Write endpoints accept a status in one of two forms, at most one per request:
List ticket statuses returns the agent’s active statuses with their ids, categories, and labels. Each status has two labels:
externalLabel is what the customer sees, internalLabel is what the dashboard shows.
Assignment and routing
When you create a ticket, the assignee fields decide whether auto-assignment runs.assigneeId and assigneeEmail are a mutually exclusive pair; sending both is a 400.
Update a ticket never auto-assigns. Omitted fields keep their current value,
assigneeId: null unassigns the ticket, and teamId: null clears the team.
List teams returns the agent’s teams; exactly one is the default.
Messages
A ticket’s thread contains three message types:
Add a message to a ticket currently accepts only
type: "reply", attributed to a team member via authorId or authorEmail. The body is GitHub-flavored Markdown; raw HTML is stripped. Delivery to the customer is asynchronous, so a 201 means the reply was recorded, not that it reached the customer.
Endpoints
List tickets
Filterable, sortable, paginated list
Search tickets
Free-text search over ticket messages
Create a ticket
Open a ticket on behalf of a customer
Get a ticket
Retrieve a single ticket by number
Update a ticket
Change status, assignee, or team
List ticket messages
Read a ticket’s thread
Add a message to a ticket
Post an agent reply
List teams
The agent’s teams and the default
List ticket statuses
Configured statuses with ids and labels
Error codes
Helpdesk-specific error codes beyond the standard authentication and rate-limiting errors:| Code | HTTP | Description |
|---|---|---|
TICKET_NOT_FOUND | 404 | No ticket matches this number for the agent. |
CONVERSATION_NOT_TAKEN_OVER | 409 | The ticket is linked to a live conversation that has not been taken over from the AI agent, so a human reply cannot be posted. Take over the conversation from the dashboard first. |
MESSAGE_CONTENT_NOT_RENDERABLE | 422 | The message body rendered to empty HTML. This happens when it consists only of raw HTML, which is stripped. Send Markdown or plain text. |
TICKET_INVALID_STATUS | 422 | statusId does not belong to a status for this agent. |
TICKET_ARCHIVED_STATUS | 422 | statusId refers to an archived status, which cannot be applied. |
TICKET_TEAM_MEMBER_NOT_FOUND | 422 | Neither assigneeId nor assigneeEmail resolved to a team member on this account. |
TICKET_TEAM_NOT_FOUND | 422 | teamId does not belong to a team for this agent. |
TEAM_MEMBER_NOT_FOUND | 422 | On message creation, neither authorId nor authorEmail resolved to a team member on this account. |
