List tickets API

This article and the rest of the API documentation in this section are written for a technical audience — integrators and developers connecting external systems to Tickiti. Familiarity with HTTP, REST, JSON and bearer-token authentication is assumed.

The list endpoint returns the ticket list as Tickiti itself renders it — through a perspective. A perspective is a saved view (its filters, conditions and ordering) configured in the Tickiti interface; the API runs the same query the staff ticket browser does, so the results, ordering and permission filtering match exactly what the acting user would see on screen.

Use it to mirror a Tickiti queue into an external dashboard, to poll for tickets matching a saved filter, or to reconcile state between Tickiti and another system.

Endpoint

POST /api/v1/tickets/query

Headers

  1. Authorization: Bearer YOUR_TOKEN — required. Token must have the tickets:read ability. A tickets:write token also works (write implies read).
  2. Content-Type: application/json — required. No Idempotency-Key is needed (this is a read).

Body

All fields are optional. With an empty body the endpoint returns the built-in All perspective.

  1. perspective_id — the numeric id of the perspective to query. This is the most direct selector.
  2. search_object.search_perspective — alternatively, select a perspective by name (e.g. "All").

Results are always scoped by the permissions of the staff user the token acts as: queues that user cannot see are excluded, and a non-staff owner is restricted to the All perspective. This means a token can never read tickets its owner could not read in the interface.

Searching with criteria

Instead of (or as well as) selecting a saved perspective, pass search_object.criteria to apply ad-hoc filters — the same ones the ticket browser’s search bar builds. Each entry is a { "mode": ..., "tokens": [...] } pair: mode names the field to match and tokens is an array of values. Criteria that share a mode are combined with OR; criteria of different modes are combined with AND. So [{"mode":"status","tokens":["open"]},{"mode":"queue","tokens":["Sales"]}] reads “open tickets in the Sales queue”.

The available modes are advertised at runtime as available_modes by the search-items endpoint, so a client can discover them rather than hard-coding the list:

ModeMatches
subjectTicket subject contains the token (substring).
contentAny response body or tag comment contains the token.
subject_contentSubject or any response body contains the token.
assignedAssigned-to email (exact).
participantA participant email contains the token.
priorityPriority value (exact).
raisedOriginator (raiser) email contains the token.
queueQueue name (exact).
statusTicket status — open, closed, on-hold, … (exact).
watchlistId of a watchlist the ticket is on.
hashtagTicket carries the hashtag (a leading # is optional).
ticket_number6-digit ticket number (exact).
created_fromTicket raised on or after a YYYY-MM-DD date.
created_toTicket raised on or before a YYYY-MM-DD date.
updated_fromLast activity on or after a YYYY-MM-DD date.
updated_toLast activity on or before a YYYY-MM-DD date.

Most modes are substring (LIKE) matches; assigned, priority, queue, status and ticket_number are exact. The four date modes take a single YYYY-MM-DD token and compare as UTC. A lone ticket_number token (or any 6-digit token prefixed with #) is treated as a direct ticket lookup.

By default the endpoint returns a single row. Set row_limit — at the top level of the body, not inside search_object — to the number of rows you want back.

Example

Query by saved perspective:

curl -X POST https://support.sole-provider.example/api/v1/tickets/query \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "perspective_id": 3
  }'

Or search with criteria — open Sales tickets, up to 50 rows:

curl -X POST https://support.sole-provider.example/api/v1/tickets/query \
  -H "Authorization: Bearer $TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "row_limit": 50,
    "search_object": {
      "criteria": [
        { "mode": "status", "tokens": ["open"] },
        { "mode": "queue", "tokens": ["Sales"] }
      ]
    }
  }'

Successful response

An array of ticket rows, each summarising one ticket. The exact columns follow the perspective, but the core fields are stable:

{
  "ok": true,
  "data": [
    {
      "ticket_id": 1,
      "number": 220009,
      "status": "open",
      "queue": "Returns",
      "priority": "20",
      "subject": "Carbon plate cracked on first marathon",
      "assigned_to_email": "[email protected]",
      "originator_email": "[email protected]",
      "created_at": "2026-05-01 09:14:02",
      "updated_at": "2026-05-02 11:30:48"
    }
  ]
}

The list is the same materialised, cached set the ticket browser uses, so it reflects the latest ticket state at query time. Poll it on a sensible interval rather than in a tight loop.

Error responses

  1. 404 not_found — the requested perspective_id or name does not exist.
  2. 401 unauthenticated — bad or missing token.
  3. 403 forbidden — token does not have the tickets:read (or tickets:write) ability.

To read a full conversation behind a row, follow up with the Show ticket API. See the API overview for the shared request and authentication conventions.