In this article, we will demonstrate the querying functionality of the Jira Align REST API so that you can more effectively build performant integrations, mass update information, or get the specific information that you need.
The Jira Align REST API uses resource expansion, which means that some parts of a resource are not returned unless specified in the request. This simplifies responses and minimizes network traffic.
To expand part of a resource in a request, use the expand query parameter and specify the object(s) to be expanded.
For example, /features may return the following fields:
In contrast, /features?expand=true would provide more information on certain fields while also sending back the fields previously returned, returning the following fields (values hidden for brevity):
Custom field information
The API 2.0 supports custom fields for:
- Objectives, themes, epics, capabilities, features, stories, defects, and tasks: active custom fields visible on Details Panels Settings
- Epics: Intake tab fields, Case Development fields on the Benefits tab
POST, PUT, and PATCH commands are supported for the purposes of adding and modifying values within existing custom fields.
Making a GET call to a work item (for example, epics) will return basic information about the custom fields, such as the field ID, possible values, and the values’ corresponding IDs:
To see information about the custom fields, such as the label associated with the field or valid values for an option list, you’ll need to make a GET call to the /editmeta function on the work item. This will return information about all of the custom fields associated with that work item, including whether it is required, its data type, field name, and any allowed values if it is a multi-option field.
"name":"KF Select List",
The concrete query syntax for API 2.0 uses a dollar sign ($) before the query option, similar to that of OData. Use the dollar sign at all times, as querying is not guaranteed without its use.
$select returns only the specified properties for each entity retrieved from the request. For example, the following would only retrieve the ID, Name, and Owner fields of all features:
$top describes the number of resources to be returned. In this case, the first 20 features would be obtained:
$skip describes the number of items to be skipped and not included. In this example query, the first 220 features would be skipped, and would return the 221st feature and beyond:
When $top and $skip are used together, it first skips the described number of resources and then takes the next n resources, where n is described from $top. In this example, the request would return 50 features, starting from the sixteenth feature:
$orderby allows you to request and obtain resources in either ascending or descending order. To specify, use asc for ascending and desc for descending; this automatically defaults to ascending order when neither is specified.
For example, the first request below would order features on the title property, in ascending order, while the second request would order all features by the priority, in decreasing order:
$filter allows the user to filter on all resources returned from the API request. Only those that satisfy the given predicate with the $filter are returned.
▼ Querying in the first level of data (click to expand)
?$filter=Id gt 1
?$filter=year(createdDate) gt 2005
▼ Querying date fields (click to expand)
/features?$filter=lastUpdatedDate eq null
/features?$filter=lastUpdatedDate ne null
/features?$filter=lastUpdatedDate eq 2018-02-22T00:00:00Z
/features?$filter=lastUpdatedDate gt 2018-02-22T00:00:00Z
Note: Don't use quotes (') around date fields.
▼ Querying boolean fields (click to expand)
/users?$filter=isTimeTracking eq null
/users?$filter=isTimeTracking ne null
Note: field eq true and field eq false do not work.
Querying in sub-levels of data is currently not supported.
The API 2.0 has query syntax that allows for filters on a collection, regardless of whether that collection is a list of types or a list of entities. To do this, we use the any operator, which relies on a predicate p. When requesting and filtering on a collection of a property, if any element or entity in the collection satisfies the given predicate, that property is returned.
As filtering on a list of entities is possible, the predicate can work on primitive types and complex types.
This example request would take all epics containing a release (program increment) ID of 1:
epics?$filter=releaseIds/any(r: r eq 1)
This request would do the exact same thing, but instead of filtering on the collection releaseIds, would filter on all releases by their ID:
/epics?expand=true&$filter=releases/any(r: r/id eq 1)
Finally, this request would return all epics that are related to at least one ‘unicorn’ release:
/epics?expand=true&$filter=releases/any(r: r/title eq 'unicorn')
Currently, filtering on a collection is supported by the following endpoints:
(Expand each for more information about each endpoint. This also includes information on querying sub-levels of data when filtering the contents of a collection, seen in the section on entities in each.)
▼ Feature: /features (click to expand)
GET /align/api/2/features?expand=true&$filter=additionalProgramIds/any(x: x eq 97)
Entities (sub-level querying):
Note: You cannot filter on the teamDescription and regionId values of a program.
▼ Epic: /epics (click to expand)
GET /align/api/2/epics?expand=true&$filter=additionalProgramIds/any(d: d eq 23)
Entities (sub-level querying):
▼ Capabilities: /capabilities (click to expand)
GET /align/api/2/capabilities?expand=true&$filter=affectedCountryIds/any(d: d eq 23)
Entities (sub-level querying):
▼ User | /users (click to expand)
No endpoints are currently supported.
▼ Team | /teams (click to expand)
GET /align/api/2/teams?expand=true&$filter=communityIds/any(x: x eq 1)
▼ Story: /stories (click to expand)
GET /align/api/2/stories?expand=true&$filter=releaseVehicleIds/any(r: r eq 1)
▼ Defect: /defects (click to expand)
GET /align/api/2/defects?$filter=releaseVehicleIds/any(r: r eq 97)
▼ Releases (Program Increments): /releases (click to expand)
GET /align/api/2/releases?expand=true&$filter=programIds/any(x: x eq 1)
Entities (sub-level querying):
▼ Milestone (Objective): /milestones (click to expand)
GET /align/api/2/milestones?expand=true&$filter=programIds/any(d: d eq 23)
▼ Dependency: /dependencies (click to expand)
GET /align/api/2/products?expand=true&$filter=competitorIds/any(x: x eq 23)
▼ Theme: /theme (click to expand)
GET /align/api/2/themes?expand=true&$filter=releaseIds/any(x: x eq 23)
- Entities (sub-level querying):
▼ Release Vehicle: /releasevehicles (click to expand)
GET /align/api/2/releasevehicles?expand=true&$filter=storyIds/any(x: x eq 1)
▼ Login: /loginactivities (click to expand)
GET /align/api/2/loginactivities?$filter=logintimeutc gt
2020-09-02T11:16:46Z and logintimeutc lt 2020-09-08T11:16:46Z&orderBy=action
Most OData query based on following properties are supported:
The following operators are those allowed in filtering expressions:
e1 aop e2
where aop is any arithmetic operator below:
These arithmetic operators require both expressions to evaluate to numeric values and are typically used in filtering a collection. If either operand evaluates to null, the result is null. In order to evaluate, first, convert both the left and right-hand operands to numeric values.
- add, mul, div: The result is the application of the binary operator to these integers (integer addition, multiplication, and division respectively)
Logical operators evaluate to either true or false and are used in predicates when filtering a collection. Operations on collections and entities are not supported. These operators can be used on all primitive values.
where v is evaluated and uop is any operator below:
- not: If v is truthy, then not v evaluates to false; if v is false, not v evaluates to true.
e1 op e2
where e1 and e2 are the left- and right-hand values (respectively), and op is any operator below:
- eq: returns true if the values on both sides are equal to each other. Null is only equal to itself.
- ne: returns true if the values on both sides are not equal to each other.
- This is equivalent to comparing both values using eq, and then applying the unary not to that result.
- lt, gt: converts both values to primitives. If both values are strings, then the result is the lexicographic comparison on strings. If both values are integers, it is the normal comparison operator for integers. If either value is null, the result is false.
- lt: less than; returns true if left is strictly less than right
- gt: greater than; returns true if left is strictly greater than right
- le, ge: the procedure similar to the above. However, there is a difference in treating the null value: if both values are null, the operator returns true based on equality, otherwise returns false.
- le: less than or equal; returns true if left is less than or equal to right
- ge: greater than or equal; returns true if left is greater than or equal to right
- and: If both the left and right values are truthy, return true. Null is treated as an unknown - therefore, return false if either value is false, otherwise return null.
- or: If either the left or right values are truthy, return true. Null is treated as an unknown - return true if the other value is truthy, otherwise return null.
The string functions take in two parameters, both as strings (s1 and s2). The syntax is:
where func is any function defined below:
- contains: returns true if s2 is a substring of s1
- startswith: returns true if s1 starts with s2
- endswith: returns true if s1 ends with s2