Tickets API

Reply to a helpdesk ticket and update its status programmatically.

What this does

The Tickets API exposes the two write actions a conversational bot needs to act on a helpdesk ticket: posting a reply into the ticket's conversation, and updating its status (open / pending / on hold / resolved / closed). List and detail endpoints already exist on GET /api/v1/tickets and GET /api/v1/tickets/:id.

When to use it

Use this when a bot or external automation needs to:

  • Post a customer-facing reply, e.g. "the engineer is on the way".
  • Add an internal note that only agents see.
  • Mark a ticket resolved after the user confirms the issue is fixed.

Authentication and scopes

Requests must include Authorization: Bearer <key>. Each endpoint requires:

  • tickets:read — list/retrieve tickets (existing endpoints)
  • tickets:write — reply to a ticket, update status

Endpoints

Reply to a ticket

POST /api/v1/tickets/:id/reply

{
  "body": "The engineer should be with you within the hour.",
  "sender_type": "agent"
}

body is required (trimmed; empty replies are rejected). sender_type is optional and defaults to "agent"; pass "note" to record an internal-only note that the customer never sees.

If the ticket has no chat session yet, one is created automatically along with a synthetic visitor record (fingerprint api-<key_id>), and the ticket is updated to point at the new session — same shape as the in-app reply flow.

Response (201 Created): the created chat_messages row.

Errors:

| Code | Status | Meaning | |---|---|---| | not_found | 404 | No such ticket in this entity | | missing_field | 400 | body is missing or whitespace-only | | tickets_write_denied | 403 | API key lacks tickets:write |

Update ticket status

PATCH /api/v1/tickets/:id/status

{ "status": "resolved" }

Allowed values: open, pending, on_hold, resolved, closed. Setting resolved or closed also stamps resolved_at (handled by the underlying ticket service).

Response: the full updated ticket row.

Errors:

| Code | Status | Meaning | |---|---|---| | invalid_status | 400 | Status not in the allowed list | | not_found | 404 | No such ticket in this entity | | tickets_write_denied | 403 | API key lacks tickets:write |