Help

The query guide All help

The query guide

The query_* tools read a resource — a permission-gated table of typed columns — with one request shape. The one rule: discover columns, don't guess.

Discover first

  1. list_query_resources — what you may read (case, entity, user, time_entry, audit, broadcast, token, message, as your permissions allow).
  2. describe_resource("case") — the exact columns: name, type, label, whether it filters and sorts, the legal values of an enum column, and any permission a column needs. Column and value vocabularies can change; this call is authoritative and no document is.

The request

{"columns": ["ref", "subject", "priority", "received_at"],
 "qfilters": [["and", ["column", "status", "=", "open"], ["column", "priority", "!=", "low"]]],
 "order": [{"name": "received_at", "desc": true}],
 "limit": 50, "count": true}
  • columns — names from describe_resource.
  • qfilters — a list of filters, ANDed together. Each is ["column", <name>, <op>, <value>] or a combinator ["and" | "or" | "nand" | "nor", <filter>, …]. Ops: =, !=, >, >=, <, <=, contains, !contains, startswith, endswith, blank, !blank. Values are bound parameters: a payload matches only itself, and %/_ in a text op are literal.
  • order — columns with desc; the resource's implicit order is appended so paging is stable.
  • limit / offset / countcount: true adds full_count.
  • paging{"op": ">", "cursor": <end_cursor from the last result>} continues without gaps.
  • formatstructured (columns + row arrays), json_objects, csv, xlsx (base64); timezone renders datetimes for the file formats.
  • strict — an unknown column in a filter matches nothing by default; strict: true (or the column_strict opcode) refuses it. Use strict when a typo would hide data you're counting on.

The result

{columns: [{name, label, type, value_labels?}], rows: [[…]], has_more, start_cursor, end_cursor, full_count?}. A column's declared type is a promise about its values: an integer column returns integers, a datetime an ISO string in UTC.

Common mistakes

  • Guessing a column name. assignee_name when the column is assignee. Describe first.
  • A made-up enum value. status = "in_progress"; the values are new, open, pending_customer, pending_internal, resolved, closed. Describe first.
  • AND-ing inside one filter. Top-level qfilters already AND together; a nested and is for grouping under an or.
  • Asking for a column you can't see. It is absent from describe_resource and refused in columns; drop it.
  • Reading a snapshot as the present. Anything you read can be stale before you act on it; get_case again before you write, and pass its version.

Which tool when

  • One case by ref: get_case. A handful by a simple filter: search_cases. Anything else: query_cases.
  • The timeline of a case: query_events with ["column", "case_ref", "=", "CASE-…"].
  • What you or your team spent: list_time_entries, or query_time_entries for a range.
  • Counts for a summary: get_dashboard_summary — the same figures the rail shows.
  • A week's figures with deltas: get_weekly_report (week: any date in the week; default the last complete one) — what the Reports page shows, under your visibility.
  • Did a message arrive, and where did it land: query_messages — every email and text either way, whatever became of it (status: appended, created, unrouted, spam, duplicate for a received one; sentfailed for a sent one), with rfc_message_id for an email's Message-ID and case_ref for the case it reached. Filter on rfc_message_id, or on from and a when range. A root admin's token only. To put one right: move_message, open_message_as_case, merge_case (a full grant on messages).