Update a ticket's status, priority, assignment or tags
Change one or more scalar fields on a ticket.
/v1/tickets/{ticket_id}Editor- Operation id
- patch_ticket
- Access
- A viewer is refused.
/v1/tickets/{ticket_id}Change one or more scalar fields on a ticket.
Use this for an operator edit. A status change is validated against the
state machine before anything is written, so a refused transition leaves the
row byte-identical. A field already holding the requested value is an
accepted no-op: no write, no event, no misleading updated_at bump.
To clear a field, send its explicit flag (unassign, unassign_team,
unlink_customer). A null value means "not supplied". Naming the status
the ticket already holds is refused here, because a patch is a status-only
operation. Use POST /v1/tickets/{ticket_id}/events if you are sending a
reply that happens to carry the current status.
Send at least one field. An empty body is refused with 400
no_fields_to_update.
tags replaces the whole list. To add one tag, send the existing tags
plus the new one.
Solving a ticket does more than change a field. It stamps solved_at
and, the first time, records a CSAT request on the timeline. Changing
priority re-stamps both SLA timers from now.
The response is the full ticket detail, including its new
legal_next_states.
Tenancy: the request is scoped to one workspace, and the credential presented is what selects it. A caller with no membership in that workspace is refused with 404, which is indistinguishable from a workspace that does not exist.
Authorisation: editor, admin or owner. A viewer receives 403 insufficient_role.
Access: Authorization: Bearer carrying either a realm access token or an API key. A key must hold the tickets:write scope, and the workspace role of the person who owns it must meet the floor above.
A realm-issued access token, presented as Authorization: Bearer <token>. It acts as the person who signed in, and every operation resolves their workspace role live from the membership record.
In: header
Path Parameters
uuidRequest Body
application/json
TypeScript Definitions
Use the request body type in TypeScript.
Response Body
application/json
application/json
application/json
application/json
application/json
application/json
application/json
application/json
curl -X PATCH "https://example.com/v1/tickets/497f6eca-6276-4993-bfeb-53cbbbba6f08" \ -H "Content-Type: application/json" \ -d '{ "status": "pending", "priority": "urgent", "assignee_id": "3fe98b76-2409-5003-b75a-93e56b450433", "tags": [ "billing", "vip", "chargeback" ] }'{ "id": "5e8b0c31-7a4d-4f92-b6c8-1d3e2a5f7b90", "subject": "Card declined at checkout", "description": "Customer's Visa is declined on every attempt since Tuesday.", "status": "pending", "priority": "urgent", "source": "email", "assignee_id": "3fe98b76-2409-5003-b75a-93e56b450433", "assignee_name": "Dana Osei", "customer_id": "9f1d6c4e-6b6e-4b31-9a5b-2f1c9a4d5e60", "customer_name": "Sam Okafor", "customer_email": "sam.okafor@northwind.example", "team_id": "d907a188-148a-5522-82a6-55798ccdecb6", "team_name": "Billing", "tags": [ "billing", "vip", "chargeback" ], "metadata": { "order_id": "A-1042" }, "first_response_due": "2026-08-14T12:20:00+00:00", "resolution_due": "2026-08-15T10:20:00+00:00", "sla_breached": false, "sla_policy_id": "b6a0f2d7-4c19-4e63-8f52-7a1b9c0d3e46", "created_at": "2026-08-14T10:20:00+00:00", "updated_at": "2026-08-14T11:05:44+00:00", "legal_next_states": [ "closed", "on_hold", "open", "solved", "spam" ], "assignee_email": "dana.osei@northwind.example", "time_total_minutes": 25, "time_billable_minutes": 25, "todo_counts": { "open": 1, "done": 2, "overdue": 0 }, "events": [ { "id": "a1b2c3d4-e5f6-4a7b-8c9d-0e1f2a3b4c5d", "kind": "inbound_email", "body": "My card is declined every time I try to pay.", "meta": { "channel": "email", "external_id": "0100019180a4c1f2" }, "actor_type": "customer", "created_at": "2026-08-14T10:20:00+00:00" }, { "id": "f0e9d8c7-b6a5-4948-9382-71605f4e3d2c", "kind": "internal_note", "body": "Payment provider is returning a soft decline on this BIN.", "meta": {}, "actor_user_id": "3fe98b76-2409-5003-b75a-93e56b450433", "actor_type": "user", "actor_name": "Dana Osei", "created_at": "2026-08-14T10:41:12+00:00" } ]}Merge this ticket into another
Merge `ticket_id` (source) into `body.target_ticket_id` (winner).
Reopen a solved or closed ticket
Reopen a terminal ticket (solved/closed). Sets status=open, stamps reopened_at, emits a `reopen` event, and re-stamps SLA so the timer is honest about how long the next leg has to...