EQL Query Language
The exact grammar of Elixion Query Language, the fields it filters on, and where you can run it.
EQL is Elixion's filter language for issues. You name a field, an operator and a value, combine those with AND, OR, NOT and parentheses, and get back the issues that match.
It filters issues and nothing else. For projects, documents, people, agents and sprints, use Search.
Where you can run it
Through the Claude connector. Ask Claude something the simple filters cannot express and it uses the search_issues tool, which takes an EQL string. get_eql_help returns the grammar, and it is generated from the parser itself, so it always matches what the search accepts. See Claude connector.
Through the API. POST /api/v1/eql/query runs a query and returns matching issues. POST /api/v1/eql/validate checks a query without running it, and GET /api/v1/eql/help returns the same grammar reference.
Whichever route you take, an EQL string is a filter, not a permission. Results are always restricted to the projects your account can already see.
Syntax
A condition is a field, an operator and a value:
status = "In Progress"
Values containing spaces must be quoted. Field names are case-insensitive, and so are status, priority and type values on their own: "in progress", "In Progress" and IN_PROGRESS all resolve to the same status.
Inside an IN list, only status values are matched that way. Priority and type values in a list have to be written as the stored uppercase values, such as EPIC, SUBTASK and CRITICAL.
An unknown field name is dropped from the filter rather than rejected, so a misspelled field quietly returns more than you meant. If a query looks too broad, check your field names first.
Fields
| Field | Filters on | Aliases |
|---|---|---|
| project | the project key | |
| projectid | the project id | |
| key | the issue key | |
| summary | the title | title |
| description | the description | |
| text | title and description together | |
| status | the issue status | |
| type | the issue type | issuetype |
| priority | the priority | |
| assignee | the assignee | |
| reporter | who filed it | creator |
| created | created date | createddate |
| updated | last modified date | updateddate |
| duedate | due date | due |
| resolved | resolution date | resolutiondate |
| resolution | the resolution | |
| sprint | the sprint | |
| epic | the parent epic | |
| parent | the parent issue | |
| labels | applied labels | label |
| components | components | component |
| storypoints | the estimate in points | points |
| estimate | original estimate in hours | originalestimate |
| remaining | remaining estimate in hours | remainingestimate |
| timespent | hours logged | logged |
| blocked | whether the issue is blocked | isblocked |
| hasMergedPR | whether its delivery evidence includes a merged pull request | mergedPR |
assignee and reporter compare against a user, so use currentUser() or a user id rather than a display name.
Through the Claude connector, epic and parent accept an issue key such as PAY-42, which is the same key every issue row shows. Through the API they compare against ids.
Values
Statuses are BACKLOG, TODO, IN_PROGRESS, IN_REVIEW, TESTING, DONE and DEFERRED. "To Do", "In Progress", "In Review" and "Completed" are accepted spellings.
Priorities are TRIVIAL, LOW, MEDIUM, HIGH and CRITICAL. "Lowest" maps to Trivial and "Highest" maps to Critical, so priority = "Critical" OR priority = "Highest" is one condition written twice.
Types are EPIC, STORY, TASK, BUG, SUBTASK, SPIKE and TECH_DEBT.
Comparison operators on priority follow the declared order Critical, High, Medium, Low, Trivial, so priority <= "Medium" reads as "Medium or more severe" and returns Critical, High and Medium. Use IN for a set of priorities.
Operators
| Operator | Meaning | Example |
|---|---|---|
| = | equals | status = "Done" |
| != | not equals | status != "Done" |
| > < >= <= | comparison | created > -7d |
| ~ | contains, case-insensitive | text ~ "timeout" |
| !~ | does not contain | summary !~ "spike" |
| IN | in a list | status IN ("To Do", "In Progress") |
| NOT IN | not in a list | type NOT IN (EPIC, SUBTASK) |
| IS EMPTY | no value | assignee IS EMPTY |
| IS NOT EMPTY | has a value | duedate IS NOT EMPTY |
Combine conditions with AND, OR and NOT, and group them with parentheses.
Functions
| Function | Returns |
|---|---|
| currentUser() | the authenticated user |
| currentSprint() | the project's active sprint |
| now() | the current UTC timestamp |
| startOfDay() / endOfDay() | today at 00:00 / 23:59 UTC |
| startOfWeek() / endOfWeek() | Monday 00:00 / Sunday 23:59 UTC of this week |
| startOfMonth() / endOfMonth() | the first / last day of this month |
Relative dates
| Expression | Meaning |
|---|---|
| -7d | 7 days ago |
| +3d | 3 days from now |
| -2w | 2 weeks ago |
| -1m | 1 month ago, counted as 30 days |
| -1y | 1 year ago, counted as 365 days |
Worked queries
-- My open work
assignee = currentUser() AND status != "Done"
-- My overdue work
assignee = currentUser() AND duedate < now() AND status != "Done"
-- This sprint, still unfinished
sprint = currentSprint() AND status NOT IN ("Done", "Deferred")
-- Critical bugs nobody owns
type = "Bug" AND priority = "Critical" AND assignee IS EMPTY
-- Everything in one project, filed in the last month
project = "PAY" AND created >= -30d
-- Work that is in review but has no merged pull request behind it
status = "In Review" AND hasMergedPR = false
-- Due before the end of next week and not started
duedate <= +1w AND status IN ("Backlog", "To Do")
-- Anything mentioning a word in the title or the description
text ~ "authentication"
Ordering and paging
EQL has no ORDER BY clause. Results always come back newest first by creation date.
Through the connector, search_issues returns 25 rows by default and at most 50; narrow the query rather than paging. Through the API, the query endpoint paginates.
When a query surprises you
Too many results. Check every field name. A misspelled field is dropped from the filter instead of raising an error, which widens the query silently. get_eql_help and GET /api/v1/eql/help list the field names the parser actually accepts.
A syntax error naming a position. The parser reports "Expected field name", "Expected operator" or "Expected value" and the character it stopped at. Usually a missing quote around a value with a space, an unmatched parenthesis, or a typo in AND or OR.
A query with no operators. Plain words with no field, operator or keyword are not an error: the query is rewritten as text ~ "<your words>" and run as a text search.
A warning next to your results. project = "PAY-42" comes back with a warning that the value looks like an issue key rather than a project, and suggests key = "PAY-42".
No results. Cut the query back to one condition and add the rest one at a time. Remember that Cancelled and Open are not statuses here: the equivalents are Deferred, and Backlog or To Do.
For word-based search across everything else, see Search.