Search and JQL reference
Orbit searches work with a JQL-style query language. This page documents the subset Orbit implements. It is a typed language compiled to parameterized SQL: nothing from a query is pasted into SQL text. It is not a complete copy of Jira’s JQL, and an unsupported construct returns an explicit error.
Examples
Section titled “Examples”project = ORB AND (status = "To Do" OR status = "In Progress") AND assignee = currentUser() ORDER BY priority DESC, updated DESCtype = bug AND priority IN (highest, high) AND labels = frontendassignee IS EMPTY AND sprint IN (openSprints())created >= -7d AND text ~ "workspace" ORDER BY created DESCGrammar
Section titled “Grammar”ORbinds loosest, thenAND, thenNOT.!,&&and||are accepted. Parentheses group.- Words are case-insensitive.
- Values with spaces or reserved characters are quoted with
"or'. Inside quotes the escapes are\",\',\\,\n,\t,\rand\uXXXX. - Reserved words (
AND,OR,NOT,IN,IS,EMPTY,NULL,ORDER,BYand others) must be quoted to be used as values. - Limits: 10,000 characters, 500 terms, 100 values in a list, 40 levels of nesting and 5
ORDER BYfields.
Fields
Section titled “Fields”project, key (also issuekey, issue), summary, description, text, type (issuetype), status, statusCategory, priority, resolution, assignee, reporter, watcher, sprint, epic ("epic link"), parent, labels (label), component (components), fixVersion (fixversions), storyPoints ("story points"), rank, created, updated, resolved, due (duedate) and startDate.
Custom fields you can see are used by name (quoted when it has spaces) or as cf[<fieldId>]. Same-named custom fields of one kind, for example one per project, are searched together. Same-named fields of different kinds are an error that names each cf[...].
Operators
Section titled “Operators”| Field type | Operators |
|---|---|
| Text | ~ and !~ (contains, ignoring case; * matches any characters and ? one), = and != (whole value, ignoring case) |
| Numbers, dates, priority, keys | also <, <=, >, >=. Priority compares by its position in the priority list. Keys compare within the key’s project. |
| Every field except text | IN and NOT IN |
| Fields that can be empty | IS EMPTY, IS NOT EMPTY (or NULL) |
As in Jira, != and NOT IN never match an empty field. Multi-valued fields (labels, components, versions, watchers, multi-select custom fields) match when any value matches. A comparison the field’s type does not support is an error, never an empty result.
Custom fields follow their kind: text, paragraph and URL as text; number; date; date-time; select and multi-select by option name or id (an unknown option is an error that lists the options); cascading by parent or child option; user; group (by id or name); and checkbox (true or false).
Functions
Section titled “Functions”| Function | Meaning |
|---|---|
currentUser() |
The person running the query |
membersOf(group) |
Members of a group |
openSprints(), futureSprints(), closedSprints() |
Sprints by state |
releasedVersions([project]), unreleasedVersions([project]) |
Versions by state |
latestReleasedVersion([project]), earliestUnreleasedVersion([project]) |
One version |
now() |
The current moment |
startOfDay, endOfDay, startOfWeek, endOfWeek, startOfMonth, endOfMonth, startOfYear, endOfYear |
Period boundaries, with an optional increment such as (-1) or ("+2w") |
A list function may follow IN without parentheses. = and != with a list function mean IN and NOT IN, so older saved filters that write sprint = openSprints() still work. An unknown function, or one used on a field of another type, is an error.
Dates and time zones
Section titled “Dates and time zones”2026-10-31, 2026/10/31 and "2026-10-31 14:30" are read in the time zone of your profile (UTC when none is set), and so are the start and end functions. A period from now such as -7d, 2w, -4h or -1w2d is relative to the moment of the search. Units are w, d, h and m. Increments of the start and end functions also take M and y.
Sorting
Section titled “Sorting”ORDER BY takes up to five fields, each ASC or DESC, on sortable fields including rank, priority (by position), key (project key, then number), and number, date and text custom fields. Empty values sort last in either direction. Every sort ends with the work item id, so pages are stable. Without ORDER BY, results come newest-updated first.
History: WAS, WAS IN and CHANGED
Section titled “History: WAS, WAS IN and CHANGED”status, assignee, reporter, priority, resolution, fixVersion and sprint keep a searchable history. Other fields refuse WAS and CHANGED and list the fields that have history.
| Form | Matches |
|---|---|
field WAS value |
Work whose field held the value at any time, now included |
field WAS IN (...) |
Held any of the values |
field WAS NOT value, WAS NOT IN (...) |
Never held it |
field CHANGED |
The field changed after creation |
Predicates may come in any order, each at most once:
AFTER date,BEFORE date,ON date(that day in your time zone) andDURING (from, to)(a date-onlytoincludes that day)BY personorBY (person, ...): names, e-mails, ids,currentUser()ormembersOf()- for
CHANGEDonly,FROM valueandTO value
status WAS "In Progress" DURING (startOfMonth(-1), endOfMonth(-1))assignee CHANGED BY currentUser() AFTER -7dpriority CHANGED FROM low TO highNOT status CHANGEDFull-text search
Section titled “Full-text search”text ~ fullText("release planning") is an Orbit extension that uses an index over the summary and the description. It takes one quoted argument of 1 to 500 characters, only on text with a positive ~. Negate the clause with NOT (text ~ fullText("query")). A quoted phrase, OR and a minus-prefixed exclusion work inside the argument. A query with full-text clauses and no ORDER BY returns the best matches first; an explicit ORDER BY always wins.
Word forms are found: with the default languages “planning” finds “plan”. Site administrators choose one to three search languages from 30 PostgreSQL configurations. Chinese, Japanese and Korean have no word breaks and are found by substring. Comments, attachments and custom fields are not full-text indexed, and there is no fuzzy matching.
The editor
Section titled “The editor”The JQL editor on the search page suggests fields, operators, functions, values and keywords for the word at the cursor (arrow keys, Enter or Tab, Escape, Ctrl+Space). It checks the query as you type and marks the error in place. Switching to the basic mode converts a query that basic filters can express, or says why it stays in JQL.
An invalid query returns HTTP 400 with code: "invalid_jql" and the position and end of the problem, counted in Unicode code points from 0.
Limits
Section titled “Limits”- Search, value suggestions, exports and saved-board columns stop after 8 seconds and answer HTTP 503 with advice to narrow the query.
- A page has at most 200 results, and
startAtis at most 100,000. - Results are cached for 15 seconds per person. Add
consistency=primaryto read straight from the database.
The search page URL
Section titled “The search page URL”The search page keeps its state in the URL: smode, stext, stextmode, sproject, stype, sstatus, sassignee, ssort, jql, spage and ssize. A link such as /?jql=status%3Ddone&spage=2#search opens that search and page.
The capability manifest
Section titled “The capability manifest”GET /search/jql/manifest lists what the engine supports: fields with aliases, types and operators, functions, keywords, limits, and what is unsupported, including the custom fields you can see. POST /search/jql/parse with { "jql": "..." } checks a query without running it, and GET /search/jql/suggestions?field=&value= returns up to 15 values for a field. See the API overview.
curl -H "Authorization: Bearer opt_..." \ "https://acme.orbit.inortix.com/api/v1/search?jql=project%3DORB%20AND%20type%3Dbug&startAt=0&maxResults=50"Status
Section titled “Status”All of the above is built. Saved filters and subscriptions are covered on their own page.