Repository navigation
Project Search
B-450 core foundation accepted on Helm 213; history/reporting functions accepted on Helm 214, 2026-10-17. This is a supported core JQL-style dialect; it does not claim full Jira JQL compatibility.
Open Projects → Search work items. Enter a query and select Search. Empty queries show all work in your accessible, active projects. Results are paged at 50 records. Use Save this query, check the separate Query to save field, enter a name, choose sharing and save. Saving returns to the saved filter and shows a confirmation. Owners can update or delete their definitions; viewers can add personal favourites.
Examples:
project = WEB AND assignee = currentUser() ORDER BY updated DESC
priority IN (highest, high) AND resolution IS EMPTY
(summary ~ "upgrade*" OR labels = maintenance) AND due < startOfDay()
parent = WEB-12
assignee IS EMPTY OR labels = unassigned
A shared filter publishes its query text, not access to the records it finds. The query runs as each viewer. Losing project membership removes its work from searches and its project-shared definitions from other viewers, even if favourited.
-
AND,OR,NOT, parentheses.NOTbinds first, thenAND, thenOR. -
=,!=,IN,NOT IN,IS EMPTY,IS NOT EMPTY. -
<,<=,>,>=for dates and numbers. -
~,!~for summary, description and text. Matching is case-insensitive substring search with*and?wildcards; SQL%and_characters are literal. This is not Lucene syntax. - Single- or double-quoted values; backslash escapes the next character in a quoted value. Quote reserved words and multi-word values.
-
ORDER BYup to three supported fields, eachASCorDESC; stable internal ID ordering breaks ties. Null values sort last. - Negative field operators exclude empty fields. Add
OR field IS EMPTYwhen empty values should match too.
| Fields | Values / behavior |
|---|---|
project |
Key or exact name, case-insensitive |
key, parent
|
Exact work item key |
type, status, category, priority
|
Stored type/status/category/priority names |
summary, description, text
|
Exact text or wildcard substring match; text checks summary or description |
assignee, reporter
|
Username, exact display name or currentUser()
|
labels, component, fixVersion, affectsVersion, resolution
|
Exact name/label |
created, updated, start, due
|
ISO dates/timestamps, supported date functions, or relative durations |
storyPoints, estimate, remaining, spent
|
Finite numeric values; time estimates and spent effort use minutes |
flagged |
true or false
|
sprint |
Sprint ID or exact name, including nested subtasks through their current parent. Completed membership is retained; removed membership is excluded. |
Aliases: issuetype, issuekey, id (work item key), duedate, startdate, createddate, updateddate, statuscategory, label, originalestimate, remainingestimate, timespent.
Sorting supports direct work item fields above, key (numeric work-item number), and priority (configured built-in priority order). Related-field sorting, such as status or project, is rejected in this first slice. Across projects, key sorting uses the number rather than lexicographic project-key order.
Date functions: now(), startOfDay(), endOfDay(), startOfWeek() (Monday), endOfWeek() (Sunday), startOfMonth(), endOfMonth(), startOfYear(), endOfYear(). All use UTC, including offset-bearing input timestamps before calendar-date comparison. Boundary functions accept one optional increment, such as startOfMonth("-1"), endOfMonth("+1M") or startOfDay("+2h"). Units are case-sensitive: y years, M months, w weeks, d days, h hours, m minutes. An omitted unit uses that function's period. Calendar arithmetic handles leap years and unequal month lengths; month-end boundaries stay at month end. now() and currentUser() take no arguments. Relative durations outside functions use m, h, d, w, for example due < -1d. Due/start fields are calendar dates, so timestamps are reduced to their UTC date.
Collection functions use IN or NOT IN, not scalar equality:
-
key IN watchedIssues()andkey IN votedIssues()search the current user's subscriptions/votes. -
key IN issueHistory()searches the current user's recorded viewed work items; it is personal viewing history, not field-change history. This implementation includes all retained view records. -
fixVersion IN releasedVersions()oraffectsVersion IN unreleasedVersions(WEB)search non-archived versions. An optional project key or exact name restricts the version source. Omitting it searches versions across accessible results.
fixVersion = latestReleasedVersion(WEB) and fixVersion = earliestUnreleasedVersion(WEB) select one non-archived version from a required accessible project, using configured version order and stable ID tie-breaking rather than release dates. These scalar functions support = and !=; missing or inaccessible projects produce no positive match. issue aliases key; affectedVersion aliases affectsVersion.
Each collection is tenant-bound, and the outer search still checks current project access. Old watches, votes or views never preserve revoked access.
CHANGED searches recorded changes to status, priority, summary, description, type, parent, start, due, storyPoints, estimate and remaining. Optional qualifiers are FROM, TO, BY, BEFORE, AFTER, and inclusive DURING (start, end). All qualifiers match one history event, rather than combining unrelated changes. BY accepts a username, exact display name or currentUser(). Date bounds accept ISO timestamps, relative durations or date functions. Dates without a time mean midnight UTC; use endOfDay() for an inclusive whole-day upper bound. Duplicate qualifiers and reversed intervals are rejected.
priority CHANGED FROM high TO low BY currentUser() AFTER startOfMonth("-1")
status CHANGED TO "Done" DURING (startOfMonth(), endOfMonth())
key IN watchedIssues() AND fixVersion IN unreleasedVersions(WEB)
Historical values compare case-insensitively against stored audit text. Long historical values inherit the existing 4,000-character audit limit. This searches actual recorded changes; initial values, deleted audit records and pre-existing missing history are not fabricated. Multi-value assignees/labels, WAS predicates and field-state reconstruction are still unsupported and fail explicitly.
Queries are bounded to 4,096 characters, 256 tokens, nesting depth 16, 100 values per list and three sort fields. Invalid or unsupported syntax returns an error position, preserves the submitted query and shows no misleading results.
- Only me: private to the owner.
- People with access to a project: visible to people who can view the selected project; setting it requires project edit access.
- Organisation: only a tenant administrator can publish to the whole tenant.
- Only the owner can update or delete a definition. Sharing and favouriting do not transfer ownership.
- Favourite requests set an explicit desired state, making repeat submissions safe.
- Definitions and favourites persist in PostgreSQL, migration
20261017_0129.
The web page lists at most 500 visible definitions and up to 500 sharing projects, with the definition bound stated in the UI; API list pagination covers larger definition sets. A filter can always be opened using its access-checked link. Owner-name uniqueness is per tenant/owner; concurrent duplicates return conflict.
Export CSV executes the current access-scoped query and sort order, independent of the current results page. Columns: Key, Project, Type, Summary, Status, Priority, Assignees, Start, Due, Story points. Export is capped at 10,000 work items; larger results return an explicit error rather than a silently truncated file. CSV quoting preserves commas/newlines, and cells that could be spreadsheet formulas are prefixed with an apostrophe. Responses are non-cacheable and UTF-8 with a BOM for spreadsheet compatibility.
All endpoints apply the same tenant, project, owner and sharing checks as the web UI. Use projects:read for reads and projects:write for mutations. These are backend capabilities; native iOS screens for saved filters are not included in this slice.
| Method/path | Contract |
|---|---|
GET /api/v1/work-item-search |
jql, optional filter ID, limit 1–200, offset 0–1,000,000. Returns existing work-item documents, total and next offset. An explicit jql overrides the selected definition for that request. |
GET /api/v1/project-filters |
Visible definitions with ownership/editable/favourite data. Supports limit/offset; returns total and next offset. |
POST /api/v1/project-filters |
Requires Idempotency-Key. JSON: name, jql, optional sharing and project_key. Returns 201; safe retries replay the result. |
PATCH /api/v1/project-filters/{id} |
Owner only; changes only supplied name/jql/sharing/project_key. |
DELETE /api/v1/project-filters/{id} |
Owner only; removes personal favourites and returns 204. |
PUT /api/v1/project-filters/{id}/favourite |
JSON {"enabled": true} or false; idempotent personal preference. |
Unknown fields, wrong JSON types, invalid queries, invalid pagination and scope failures are rejected. Other tenants/private filters return 404. OpenAPI lists each endpoint.
WAS predicates and field-state reconstruction, remaining Jira functions (including membership and linked-item functions), custom fields after their owning phase, JQL autocomplete, basic/advanced mode conversion, saved column layouts, role-specific filter sharing, subscriptions/scheduled delivery and full navigator bulk operations. Sprint models and functions are now implemented; custom-field queries still depend on the owning phase. Unsupported syntax fails explicitly. B-450 remains in progress, not complete.
- Atlassian: advanced JQL search
- Atlassian: operators
- Atlassian: functions
- Premium capability inventory
- Project implementation plan
Validation and deployment evidence
History and reporting validation
Sprint functions openSprints(), closedSprints() and futureSprints() support IN/NOT IN with no arguments. Backlog, sprint and report guide.