> ## Documentation Index
> Fetch the complete documentation index at: https://docs.visitoai.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Tickets and escalations API

> Discover durable work, manage human ownership and reconcile agent actions.

Tickets is available for workspaces enrolled in the staged Tickets rollout. Enabled workspaces support reads and writes subject to the permissions below; there is no separate read-only mode. Disabled workspaces return `TICKETS_UNAVAILABLE`. Disabling the feature preserves saved items and history; access returns when it is re-enabled.

## Items and lifecycle

General tickets and escalations are conversation-linked durable items. Multiple tickets can coexist with one unresolved escalation. Legacy manual reviews are presented as tickets with their original IDs and history; records are not copied. `requested` maps to `pending`, and `active` maps to `in_progress`.

Reading, assigning and replying do not start work. Call **Start work** explicitly. An agent must assign an active human operator before starting an unassigned item. Humans starting an unassigned item claim it. Ticket ownership is independent of conversation ownership; escalation assignment follows conversation ownership.

Open general tickets support title/description edits, assignment, internal notes, start, resolution and cancellation. Pending tickets can resolve or cancel directly. Terminal items remain readable but cannot reopen, change or be permanently deleted. Priorities, deadlines, reminders, standalone tickets and agent assignees are outside v1.

General ticket operations leave AI mode, unread state and reply attention unchanged. Escalation acceptance durably pauses AI and invalidates pending responses using canonical handoff persistence, notifications and billing. Resolution uses the exact owning case and restores AI eligibility subject to other restrictions. Completing either type does not send a customer reply or clear a separate reply obligation.

## Routes and MCP tools

All paths below are relative to `/m2m/v1`. Dashboard and mobile use the same domain services.

| Method and path | MCP operation | Required permission |
| - | - | - |
| GET /tickets | list\_tickets | tickets:read |
| GET /tickets/{ticketId} | get\_ticket | tickets:read |
| GET /tickets/{ticketId}/events | list\_ticket\_events | tickets:read |
| GET /tickets/requests/{requestId} | get\_ticket\_request\_status | tickets:read |
| POST /tickets | create\_ticket | tickets:write |
| PATCH /tickets/{ticketId} | update\_ticket | tickets:write |
| PUT /tickets/{ticketId}/assignment | assign\_ticket | tickets:write |
| POST /tickets/{ticketId}/notes | add\_ticket\_note | tickets:write |
| POST /tickets/{ticketId}/start | start\_ticket | tickets:write |
| POST /tickets/{ticketId}/resolve | resolve\_ticket | tickets:write |
| POST /tickets/{ticketId}/cancel | cancel\_ticket | tickets:write |
| POST /escalations | create\_escalation | conversations:handoffs:create |
| PUT /escalations/{ticketId}/assignment | assign\_escalation | conversations:assignment:write |
| POST /escalations/{ticketId}/notes | add\_escalation\_note | conversations:handoffs:write |
| POST /escalations/{ticketId}/start | start\_escalation | conversations:handoffs:write |
| POST /escalations/{ticketId}/resolve | resolve\_escalation | conversations:handoffs:write |

`tickets:read` exposes both item types. It does not grant conversation transcripts, message evidence, policy, action receipts or delivery status. Those supporting reads retain their existing permissions. A denied context read must be reported as permission denied; an unavailable source is not empty evidence. Responses include `contextStatus`, IDs and provenance rather than whole transcripts.

## Creation and safe mutations

Creation requires `conversationId`, a nonempty `title` (maximum 160 characters), and an `Idempotency-Key`. Description and business are optional. General tickets also accept an optional human `operatorId` and stored `sourceMessageId`; description maximum is 2,000 characters. Escalation description maximum is 800 characters; assign its human owner with the separate assignment operation after creation.

```json theme={null}
{
  "conversationId": "stored-conversation-id",
  "title": "Check the requested document",
  "description": "Confirm the information before the next reply.",
  "operatorId": "active-human-operator-id"
}
```

Subsequent mutations address the exact `ticketId` and require its current integer `revision`. Updates need at least one editable field. Assignment accepts a human operator ID or null to unassign. Notes are internal and require nonempty `note`. Revisions advance atomically; a stale mutation returns HTTP 409. Reread and decide again rather than blindly retrying. Agent audit identity is the credential/OAuth grant identity, never an impersonated human.

Creation keys are bound to the workspace, actor and exact input. An uncertain escalation response contains a `requestId`. Read `get_ticket_request_status` before retrying. `processing` and `reconciliation_required` do not confirm completion. When a ticket ID exists, inspect the item and ownership. Do not create a replacement escalation after an uncertain result. Recovery preserves accepted ownership and reconciles billing/receipt state through the operational runbook.

## Discovery, freshness and history

Lists accept `type`, `status`, `owner` (all, unassigned, or a human operator ID), `propertyId`, `channel`, `conversationId`, `updatedSince`, `limit` and `cursor`. Default page size is 25, maximum 100. Credentials fix the workspace; tenant override query parameters are rejected. Responses include `asOf`, all status counts under the other filters, `hasMore` and `nextCursor`. Lists are live, so changes may move items between pages. Continue using unchanged filters and reconcile exact items by revision.

Detail includes type, status, title, description, revision, timestamps, human assignee, source IDs, provenance and `permittedActions`. Escalations also include the saved reason, captured/missing fields, `ownershipActive` and their resolution consequence. Notes and lifecycle events paginate independently; no entire transcript is embedded.

## Agent workflow

1. Discover with `list_tickets` and continue any remaining pages.
2. Inspect `get_ticket` and `list_ticket_events`; read the relevant conversation, stored messages, policy, action receipts and delivery proof using their existing tools.
3. Select a human owner with `list_assignable_operators`; use the matching assignment tool.
4. Reread the revision, then call `start_ticket` or `start_escalation` explicitly.
5. Add internal notes containing the evidence and next step. Sending a reply uses separate sending tools and separate authorization.
6. Resolve only after the work is complete. Escalation resolution permits AI responses again subject to other restrictions.
7. Read the exact item back and inspect policy/delivery state when relevant. Reconcile conflicts and uncertain outcomes before another write.

## Events and compatibility

`ticket.created` and `ticket.updated` use existing durable outbox, RabbitMQ retry/DLQ, webhook delivery and recovery infrastructure. Envelopes contain item/conversation IDs, type, revision and change action without notes, contact details or transcripts. Subscriptions require `tickets:read`. Delivery can be duplicated or out of order; deduplicate `eventId` and reread newer item revisions. Existing handoff events remain available. Existing API keys, OAuth grants, review/handoff endpoint shapes and URLs remain valid and do not gain scopes automatically.

Tickets replaces the previous Tasks naming. Deprecated `/tasks` routes and task MCP names remain compatibility adapters returning their original `taskId`, `type=task` and `tasks` fields. Existing `tasks:read/write` grants retain equivalent authority without adding scopes. Legacy `task.created/updated` subscriptions keep their chosen event/payload shape and event identity. New integrations should use Tickets names. Stored records and audit history are not rewritten.

See [permissions](/api-docs/permissions), [webhooks](/api-docs/webhooks) and [the product guide](/product-guides/product/tickets).

## Structured knowledge-gap context

`GET /tickets/{ticketId}` and MCP `get_ticket` expose optional `escalation.knowledgeGap` for knowledge-gap escalations. This contains `contextStatus`, saved `schemaVersion`, `category`, `sourceCount`, up to five `sourceTitles` (200 characters each), and optional legacy `importance`/`confidence`. Those legacy diagnostic values are not ticket priorities. A matching saved detection can add `receipt` with `receiptId`, `reportedAt`, configured `behavior` and recorded `disposition`. Detection outcome describes the original report, independently of today's ticket status and AI eligibility.

M2M/MCP supporting context requires `conversations:read` in addition to `tickets:read`. Without it, `contextStatus=permission_denied` returns no category, source or receipt fields. Missing/malformed saved context returns `unavailable`; absent or unreadable matching detection sets `receiptStatus=unavailable`, while valid saved case context remains readable. Reports are bound to the exact tenant, conversation, initiating event and handoff case. A newer report is not substituted. Older cases need no backfill.

Queue and mutation responses remain lean and omit this detail. Read `get_ticket` for context after a mutation. Source titles identify recorded retrieval sources, not their contents or proof that each source caused the conflict. Inspect the existing conversation/message/action evidence tools for supporting details using their permissions. No provider replay, current-policy reevaluation, automatic general-ticket creation or customer reply occurs.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.