atlassian-cli is an independent, community open-source project, not affiliated with, endorsed by, or sponsored by Atlassian, and is not Atlassian's official CLI (acli). Product names are used only to identify compatibility.
A JQL query is a Jira Query Language expression that finds issues by matching fields against values. Every query follows the same shape: a field, an operator, and a value, such as status = Done. You chain clauses with AND, OR, and NOT, then sort with ORDER BY. This page is a pure reference: the operators, keywords, functions, and fields you need in one place, with examples you can paste into Jira's search bar or into atlassian-cli on the command line.
Bookmark it. Nothing here is padded with tutorials or opinion. If you want a task-oriented walkthrough of searching from a terminal, see the companion posts linked at the end. If you just need to remember what ~ does or how closedSprints() behaves, keep scrolling.
JQL Query Syntax at a Glance
A JQL query is one or more clauses joined by logical operators and optionally followed by a sort. It is not SQL: there is no SELECT, no FROM, and no joins. You are always querying issues.
# field operator value
project = DEV
# two clauses joined with AND, then sorted
project = DEV AND status = "In Progress" ORDER BY priority DESC
A few rules save most of the debugging time:
- Wrap any value containing spaces or reserved words in quotes:
status = "In Progress". - Keywords and operators are case-insensitive (
ANDequalsand), but field and value names should match Jira's spelling. ORDER BYmust come last, after every filter clause.- Use parentheses to group logic:
(priority = High OR priority = Highest) AND status != Done.
Operators
Operators compare a field to a value. Comparison operators work on most fields; the text operator ~ works only on free-text fields; the history operators (WAS, CHANGED) query how a field looked in the past.
| Operator | Meaning | Example |
|---|---|---|
= | Equals an exact value | status = Done |
!= | Not equal to | status != Done |
> >= < <= | Range comparison (dates, numbers) | created >= -7d |
~ | CONTAINS (text search) | summary ~ "login" |
!~ | DOES NOT CONTAIN | summary !~ "wip" |
IN | Matches any value in a list | status IN (Open, Reopened) |
NOT IN | Matches none of a list | priority NOT IN (Low, Lowest) |
IS | Used with EMPTY / NULL | assignee IS EMPTY |
IS NOT | Has a value | fixVersion IS NOT EMPTY |
WAS | Held a value at any past point | status WAS "In Progress" |
WAS IN | Held any value in a list | status WAS IN (Open, Reopened) |
CHANGED | Field changed (add AFTER/BY) | status CHANGED AFTER -1w |
The single most common mistake is reaching for = on a text field. summary = "login" only matches issues whose summary is exactly the word login. To find any summary that contains login, use summary ~ "login". The history operators (WAS, WAS IN, CHANGED) can be refined with the predicates AFTER, BEFORE, ON, DURING, BY, FROM, and TO.
Keywords & Logical Operators
Keywords glue clauses together and control ordering. They are the connective tissue of every JQL query.
| Keyword | Purpose | Example |
|---|---|---|
AND | All clauses must match | project = DEV AND status = Open |
OR | Any clause may match | priority = High OR priority = Highest |
NOT | Negate a clause | NOT status = Done |
EMPTY | Field has no value | fixVersion IS EMPTY |
NULL | Alias for EMPTY | resolution = NULL |
ORDER BY | Sort the result set (must be last) | ORDER BY created DESC |
ASC / DESC | Sort direction | ORDER BY priority DESC, created ASC |
An unresolved issue is best expressed as resolution = EMPTY (or resolution IS EMPTY), not status != Done. Status names differ between workflows, but the resolution field is set the moment an issue is genuinely closed, so it is the portable way to ask "still open."
Functions
Functions produce dynamic values that Jira evaluates at query time. They are what make a saved filter stay useful: assignee = currentUser() means something different for every person who runs it, and sprint IN openSprints() keeps pointing at whatever sprint is active today.
| Function | Returns | Example |
|---|---|---|
currentUser() | The account running the query | assignee = currentUser() |
membersOf("group") | Users in a group | assignee IN membersOf("developers") |
now() | Current date and time | due < now() |
startOfDay() / endOfDay() | Day boundaries (offset optional) | created >= startOfDay(-7) |
startOfWeek() / startOfMonth() | Start of the calendar period | updated >= startOfWeek() |
openSprints() | Issues in active sprints | sprint IN openSprints() |
closedSprints() | Issues in completed sprints | sprint IN closedSprints() |
futureSprints() | Issues in upcoming sprints | sprint IN futureSprints() |
latestReleasedVersion(PROJ) | Newest released version | fixVersion = latestReleasedVersion(DEV) |
unreleasedVersions(PROJ) | Versions not yet released | fixVersion IN unreleasedVersions(DEV) |
linkedIssues(KEY) | Issues linked to a given issue | issue IN linkedIssues(DEV-100) |
issueHistory() | Issues you recently viewed | issue IN issueHistory() |
Sprint functions only apply to boards that use sprints. Version functions take a project key argument so Jira knows which release schedule to read. All functions are called with parentheses even when they take no argument, for example now().
Common Fields
These are the fields you will reference most. Custom fields are queried by name or by their cf[10010] identifier; run atlassian-cli jira fields list to discover the IDs on your instance.
| Field | Matches | Example |
|---|---|---|
project | Project key or name | project = DEV |
status | Current workflow status | status = "In Progress" |
statusCategory | To Do / In Progress / Done | statusCategory = "In Progress" |
assignee | Assigned user | assignee = currentUser() |
reporter | Issue creator | reporter = jane@example.com |
type / issuetype | Issue type | type = Bug |
priority | Priority level | priority IN (High, Highest) |
resolution | Resolution (EMPTY = open) | resolution = EMPTY |
created / updated | Timestamp fields | updated >= -1d |
due | Due date | due <= endOfWeek() |
labels | Labels on the issue | labels = backend |
component | Component | component = "API" |
fixVersion | Fix version | fixVersion = 2.1 |
sprint | Sprint (name or function) | sprint IN openSprints() |
parent | Parent issue | parent = DEV-100 |
text | All text fields at once | text ~ "timeout" |
Date Filtering
Date fields accept absolute values ("2026-07-01"), relative shorthand, and functions. Relative shorthand is the fastest to type: a signed number followed by a unit. Negative values look backward from now.
| Unit | Meaning | Example |
|---|---|---|
w | Weeks | created >= -2w |
d | Days | updated >= -7d |
h | Hours | updated >= -4h |
m | Minutes | created >= -30m |
Note that m means minutes, not months, which trips people up constantly. For calendar-aligned windows use the boundary functions instead: created >= startOfMonth() catches everything since the first of the month, and due <= endOfWeek() covers the rest of the current week regardless of what day you run it.
Ready-to-Run Query Examples
Concrete queries for recurring needs. Swap DEV for your project key and run them anywhere a JQL query is accepted.
| Goal | JQL query |
|---|---|
| My open work, urgent first | assignee = currentUser() AND resolution = EMPTY ORDER BY priority DESC |
| Bugs created this week | project = DEV AND type = Bug AND created >= startOfWeek() |
| Unassigned issues in the active sprint | sprint IN openSprints() AND assignee IS EMPTY |
| Stale in-review tickets | status = "In Review" AND updated <= -14d |
| Anything mentioning "timeout" | project = DEV AND text ~ "timeout" |
| Recently reopened issues | status CHANGED TO "Reopened" AFTER -30d |
| Work for an upcoming release | fixVersion IN unreleasedVersions(DEV) AND resolution = EMPTY |
| High-priority, no due date | priority IN (High, Highest) AND due IS EMPTY |
Running JQL from the Command Line
Any JQL query in this cheat sheet runs unchanged through atlassian-cli. Pass the query to the --jql flag on jira issue search, and pick an output format that suits what you are doing next.
# Basic search, table output
atlassian-cli jira issue search --jql "project = DEV AND status = 'In Progress'"
# My open work, most urgent first, top 20
atlassian-cli jira issue search \
--jql "assignee = currentUser() AND resolution = EMPTY order by priority desc" \
--limit 20
# Export recent bugs to CSV
atlassian-cli jira issue search \
--jql "project = DEV AND type = Bug AND created >= -30d" \
--format csv --output recent-bugs.csv
# Pipe JSON into jq to pull just the issue keys
atlassian-cli jira issue search \
--jql "sprint IN openSprints() AND status != Done" \
--format json | jq '.[].key'
The same JQL drives bulk actions. Preview with --dry-run first, then remove it to execute against every matching issue:
# Close stale in-review tickets (preview first)
atlassian-cli jira bulk transition \
--jql "project = DEV AND status = 'In Review' AND updated < -14d" \
--transition "Done" \
--dry-run
Add --profile <name> to target a specific site, and see the full flag list in the command reference. Every command group accepts --format table|json|csv|yaml|quiet|markdown.
How this differs from Atlassian's own CLI: atlassian-cli is an independent, community open-source project. It is not Atlassian's official CLI (acli) and is not affiliated with Atlassian. Use the official acli for first-party vendor support; use atlassian-cli if you want a single free Rust binary spanning Jira, Confluence, Bitbucket, and JSM. The JQL syntax itself is identical no matter which tool sends the query, because JQL is evaluated server-side by Jira.
Run these queries in seconds
Install the single Rust binary and paste any JQL query straight into your terminal.
Try atlassian-cliFAQ
What is a JQL query in Jira?
JQL (Jira Query Language) is a structured query syntax for finding Jira issues. A JQL query is built from three parts: a field, an operator, and a value, for example status = Done. You combine clauses with AND, OR, and NOT, then sort results with ORDER BY. JQL is not SQL; it queries issues only, and there is no SELECT or FROM.
How do I write a JQL query for issues assigned to me?
Use the currentUser() function: assignee = currentUser() AND resolution = Unresolved. This returns your open issues across every project. Add order by priority desc to see the most urgent first, or scope it to one project with project = DEV AND assignee = currentUser().
What is the difference between = and ~ in JQL?
The = operator matches an exact value, so summary = "login bug" only matches that precise string. The ~ operator is the CONTAINS operator for text search, so summary ~ "login" matches any summary containing the word login. Use ~ for free-text fields like summary, description, comment, and text; use = for exact fields like status or priority.
Can I run JQL queries from the command line?
Yes. With atlassian-cli you pass any JQL query to the --jql flag: atlassian-cli jira issue search --jql "project = DEV AND status = 'In Progress'". Add --format json, --format csv, or --limit to shape the output, and pipe JSON into jq for further filtering.
How do I filter Jira issues by date in JQL?
Use relative date shorthand with the date fields created, updated, due, and resolved. For example created >= -7d finds issues created in the last seven days. The units are w (weeks), d (days), h (hours), and m (minutes). Functions like startOfWeek() and endOfMonth() anchor queries to calendar boundaries.