Split Agent Ticket
POST/api/support/agent/tickets/:ticket/split
Moves some of this ticket's messages into a brand-new ticket for the same requester and tenant, and returns the new ticket. Use it when one thread turns out to hold two separate problems.
support:writeGrant this scope to your token under Settings → Developer → Personal Access Tokens.
What happens:
- a new ticket is created with the given
subject, copying the source's tenant, requester, type, priority, visibility, group, context, tags and SLA policy; it opens with statusopen, sourceagent, no assignee, fresh SLA due dates computed from now, and the caller ascreated_by_user_id - every participant of the source (requester, CCs, watchers) is copied onto the new ticket with the same role
- the chosen messages and their attachments are moved off the source onto the new ticket; the new ticket's
last_customer_message_atis the latest moved customer message - the two tickets are cross-linked with
ticketlinks ("Split from #<source>" on the new ticket, "Split off as #<new>" on the source) - a
createdevent and asplitevent are recorded on the new ticket, and asplitevent on the source
The split is silent: no acknowledgement email is sent for the new ticket and the new-ticket automations (rules, AI triage) do not run for it. The source keeps its status, assignee and remaining messages.
Path parameters
ticket(integer) — the source ticket id.
Request body
message_ids[](array of integers, required, 1–200 items, distinct) — the messages to move; every id must belong to this ticket (public replies and internal notes both qualify)subject(string, required, max 255) — the new ticket's subject
Response — data is the full agent view of the new ticket:
id(integer),number(string, e.g.#2451),tenant_id(string, nullable),subject(string)type(string, nullable) — one of: bug, question, feature_request, billing;type_label(string, nullable)status(string) — one of: open, in_progress, waiting_on_customer, awaiting_release, resolved, closed;status_label(string) — the agent-facing labelpriority(string) — one of: low, medium, high, urgentsource(string) — one of: app, email, api, assistant, agent, importvisibility(string) — tenant or requesterrequester({id, name, email};idis null when the requester is not a user) andassignee({id, name, email}, nullable)context(object, nullable) — what the app captured when the ticket was raised;tags[](array of strings)sla—first_response_due_at,resolution_due_at,first_responded_at,resolved_at,closed_at(ISO-8601, each nullable)first_response_sla_status/resolution_sla_status(string) — one of: on_track, breaching_soon (past the policy's warning fraction of the target), breached, paused (the ticket is waiting on the customer), metmerged_into({id, number}, nullable) — set once this ticket was merged into anotherpublic_messages_count(integer),note_count(integer) — customer-visible messages and internal noteslast_customer_message_at,last_agent_message_at(ISO-8601, nullable),reopened_count(integer)csat({score, comment, at}, nullable)participants[]— {id, user_id, name, email, role (requester | cc | watcher), notify}links[]— {id, kind (jira | sentry | deploy | record | ticket | url), ref, url, label, created_at}group_key(string, nullable),external_ref(string, nullable — the id in the previous help desk, e.g.FD-9184),merged_into_ticket_id(integer, nullable),sla_policy_id(integer, nullable),created_by_user_id(integer, nullable)sla_paused_at(ISO-8601, nullable) — set while the resolution clock is pausedsnoozed_until(ISO-8601, nullable) andis_snoozed(boolean — true whilesnoozed_untilis in the future)follow_up_at(ISO-8601, nullable) — the agent's own reminder, never customer-facingai[]— the latest completed, non-withheld AI run of each kind: {id, kind (triage | draft), status, model, output, withheld, withheld_reason, accepted, created_at}created_at,updated_at(ISO-8601)
Authentication: Bearer token with the support:write scope, or an authenticated session, from a caller with an active support role that can work tickets (the viewer role is read-only). No tenant context — this endpoint is central.
If this ticket was merged into another ticket, the request is refused with a 422 whose merged_into (id, number) names the live ticket — send the action there instead.
Request
Responses
- 201
- 401
- 403
- 404
- 422
- 429
Created
Response Headers
Unauthorized
Response Headers
Forbidden
Response Headers
Not Found
Response Headers
Unprocessable Content
Response Headers
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.