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
list_query_resources— what you may read (case,entity,user,time_entry,audit,broadcast,token,message, as your permissions allow).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 / count —
count: trueaddsfull_count. - paging —
{"op": ">", "cursor": <end_cursor from the last result>}continues without gaps. - format —
structured(columns + row arrays),json_objects,csv,xlsx(base64);timezonerenders datetimes for the file formats. - strict — an unknown column in a filter matches nothing by default;
strict: true(or thecolumn_strictopcode) 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_namewhen the column isassignee. Describe first. - A made-up enum value.
status = "in_progress"; the values arenew,open,pending_customer,pending_internal,resolved,closed. Describe first. - AND-ing inside one filter. Top-level
qfiltersalready AND together; a nestedandis for grouping under anor. - Asking for a column you can't see. It is absent from
describe_resourceand refused incolumns; drop it. - Reading a snapshot as the present. Anything you read can be stale before you act on it;
get_caseagain before you write, and pass itsversion.
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_eventswith["column", "case_ref", "=", "CASE-…"]. - What you or your team spent:
list_time_entries, orquery_time_entriesfor 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,duplicatefor a received one;sent…failedfor a sent one), withrfc_message_idfor an email's Message-ID andcase_reffor the case it reached. Filter onrfc_message_id, or onfromand awhenrange. A root admin's token only. To put one right:move_message,open_message_as_case,merge_case(afullgrant on messages).