JMESPath is a query language for JSONExamples and a JMESPath tutorial can be found at the JMESPath site. It is used by the field code Action response details and the JWT parser function getFromJSON()

We describe how to get data from JSON objects which are returned as response from an action in after sending a REST request defined by the Atlassian Jira REST API.


How to work with JMESPath in general

We introduce the main search terms that allow you to extract the relevant information from a response. For more complex ones, please have a look at the JMESPath specification.

{
  "firstLevelAttribute": "This is the value of a first level attribute",
  "boolean": true,
  "jsonAttribute": {
    "firstName": "John",
    "lastName": "Doe"
  },
  "emptyList": [],
  "emptyJSON": {
  },
  "number": 42,
  "null": null,
  "listWithJSON": [
    {
      "key": "1",
      "name": "Sue",
      "city": "Sydney"
    },
    {
      "key": "2",
      "name": "Jeff",
      "city": "Washington"
    },
    {
      "key": "3",
      "name": "Sergej",
      "city": "Sydney",
    },
    {
      "key": "4",
      "name": "Ayse",
      "city": "Washington",
    }
  ],
  "listWithComplexJSON": [
    {
      "key": "1",
      "name": {
        "first": [
          "Tom",
          "Bob"
        ],
        "last": "Miller"
      }
    },
    {
      "key": "2",
      "name": {
        "first": [
          "John",
          "Jane"
        ],
        "last": "Doe"
      }
    }
  ],
  "differentNameStructure": [
    {
      "key": "value1",
      "name": {
        "first": [
          "Tom",
          "Bob"
        ],
        "last": "Miller"
      }
    },
    {
      "key": "value2",
      "person": {
        "first": [
          "John",
          "Jane"
        ],
        "last": "Doe"
      }
    }
  ]
}


you can access the values as described in the table below.

What to getJMESPathExample
Attributes on the first levelUse the name of the attribute.


JMESPathResultNotes
firstLevelAttributeThis is the value of a first level attribute
jsonAttribute{ "firstName": "John","lastName": "Doe" }
emptyList
The empty list is converted to an empty string
emptyJSON{}
booleantrue
number42
null
The null value is converted to an empty string
notExisting
If the attribute does not exist, an empty string is returned



Attributes on a lower JSON levelUse the path to this attribute. 
JMESPathResult
jsonAttribute.firstNameJohn
Access a certain element of a list attributeUse the index of the list
JMESPathResultNotes
listWithComplexJSON[0]

{ "key": "1", "name": { "first": [ "Tom", "Bob" ], "last": "Miller" } }

The first element of a list has the index 0
listWithJSON[1]{ "key": "2", "name": "Jeff" }
Get attributes of all list elementsUse the * instead of an index and add the attribute name/path
JMESPathResultNotes
listWithJSON[*].nameSue,Jeff,Sergej,Ayse
listWithJSON[*]{ "key": "1", "name": "Sue" }, { "key": "2", "name": "Jeff" }, { "key": "3", "name": "Sergej" }, { "key": "4", "name": "Ayse" }You can achieve the same result by
listWithJSON
listWithComplexJSON[*].name.lastMiller,Doe

Get a certain attribute of all elements and all level

Use 

[*]and .*. in combination

* in a path means "all values at this level"

[] flattens the result if it is a list (or a list of lists)

JMESPathResultNotes
differentNameStructure[*]


[{"key":"value1","name":{"first":["Tom","Bob"],"last":"Miller"}},{"key":"value2","person":{"first":["John","Jane"],"last":"Doe"}}]

Get all elements of the list differentNameStructure

differentNameStructure[*].*

[["value1",{"first":["Tom","Bob"],"last":"Miller"}],
["value2",{"first":["John","Jane"],"last":"Doe"}]]

Now get all elements of the next level (i.e. all values of the "key", "name" and "person" elements)

This is a list of lists

differentNameStructure[*].*.last

[["Miller"],["Doe"]]

Getting only the last names of the structure (if available)

This is still a list of lists (with only one element)

differentNameStructure[*].*.last[]

Miller,DoeThe operator [] flattens the result
Filter dataAdd a comparison as index for an array
JMESPathResultNotes
listWithJSON[?city == 'Washington'][{"key":2,"name":"Jeff","city":"Washington"},{"key":4,"name":"Ayse","city":"Washington"}]
listWithJSON[?city == 'Washington' ].{key: key, name:name}[{"key":2,"name":"Jeff"},{"key":4,"name":"Ayse"}]
Compose new JSON out of the existing oneAdd the structure of the new JSON
JMESPathResultNotes

listWithJSON.{index: to_string(key), name:name}

[{"index":"1","name":"Sue"},{"index":"2","name":"Jeff"},{"index":"3","name":"Sergej"},{"index":"4","name":"Ayse"}]Build a different structure where the key is called "index" and is a text and not a number. Leave out the attribute "city". This structure may be requested from a different function.
listWithJSON[?city == 'Washington'].{index: key, name:name}[{"index":2,"name":"Jeff"},{"index":4,"name":"Ayse"}]Combine a filter with a structure.
Attribute is not availableIf an attribute/path is entered which does not exist in the JSON, null is returned
JMESPath
doesNotExist
firstLevelAttribute.doesNotExist
jsonAttribute.doesNotExist
jsonAttribute.first.doesNotExist
listWithJSON[200]
How to work with JMESPath in JWT expressions

JMESPath is used by the field code Action response details and the parser function  getFromJSON()

Syntactic rules

Escaping certain characters

When used in Action response details, the curly brackets have to be escaped: 

characterescaped character
{\{
}\}

Example:

%{action.response.listWithComplexJSON[].\{"fullname":name.last\}}


When used in getFromJSON(), the quote has to be escaped

characterescaped character
"\"
Example:

The custom field with the custom ID 10010 holds the value

"listWithComplexJSON": [
    {
      "key": "1",
      "name": {
        "first": [
          "Tom",
          "Bob"
        ],
        "last": "Miller"
      }
    },
    {
      "key": "2",
      "name": {
        "first": [
          "John",
          "Jane"
        ],
        "last": "Doe"
      }
    }
  ]
%{getFromJSON(%{issue.cf10010},"listWithComplexJSON[].{\"fullname\":name.last}")}
Parser expressions in JMESPath
You cannot use JWT field codes or parser expressions in JMESPath itself.

Conversion from JSON types to string

They always return a text, e.g. the boolean value true will be converted to the string value true, an array with elements of a flat data type (e.g. number) will be a comma separated string of the array elements. The null value is represented as an empty text.

If the result is not 

  • null

  • boolean

  • string

  • number

but a JSON object itself, this JSON object will be converted to a text with JSON.stringify

The same is done if an array does not hold flat values but JSON objects.

These results may be stored in a custom field and being read with the new parser function getFromJSON() in a different post function. 

Cast the text results

In case the result is not a text but e.g. a number or an array, you can cast it using the known functions from the parser like toNumber() or toStringList() and used as input for other parser functions or to set a field in post function like Create issue.

JWT parser expressionResultNote
%{toStringList(%{action.response.fields.fixVersions[*].name})}v2,v5
%{first(toStringList(%{action.response.fields.fixVersions[*].name})}v2This is equivalent to %{action.response.fields.fixVersions[0].name}
%{toNumber(%{action.response.fields.customfield_10042})}21
How to use JMESPath for a Jira REST API response

The following JSON is an excerpt of the response returned by a GET /rest/api/3/issue call for issue PU-670

{
  "id": "11986",
  "self": "https://your-domain.atlassian.net/rest/api/2/issue/11986",
  "key": "PU-670",
  "fields": {
"summary": "Get the data from the database", "labels": [ "Backend", "Frontend" ], "creator": { "self": "https://your-domain.atlassian.net/rest/api/2/user?accountId=557058%3A145e0983-5707-439c-80e4-1160dd57f113", "accountId": "557058:145e0983-5707-439c-80e4-1160dd57f143", "emailAddress": "not.me@decadis.de", "avatarUrls": { "48x48": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/557058:145e0983-5707-439c-80e4-1160d57f114/9f9c7a9a-460d-41e2-825e-859866ae81c6/48", "24x24": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/557058:145e0983-5707-439c-80e4-1160d57f114/9f9c7a9a-460d-41e2-825e-859866ae81c6/24", "16x16": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/557058:145e0983-5707-439c-80e4-1160d57f114/9f9c7a9a-460d-41e2-825e-859866ae81c6/16", "32x32": "https://avatar-management--avatars.us-west-2.prod.public.atl-paas.net/557058:145e0983-5707-439c-80e4-1160d57f114/9f9c7a9a-460d-41e2-825e-859866ae81c6/32" }, "displayName": "Who am I", "active": true, "timeZone": "Europe/Berlin", "accountType": "atlassian" }, "statuscategorychangedate": "2021-11-11T00:58:58.197-1100", "fixVersions": [ { "self": "https://your-domain.atlassian.net/rest/api/2/version/10003", "id": "10003", "description": "", "name": "v2", "archived": false, "released": true, "releaseDate": "2020-04-28" }, { "self": "https://your-domain.atlassian.net/rest/api/2/version/10006", "id": "10006", "description": "", "name": "v5", "archived": false, "released": false } ], "issuelinks": [ { "id": "10292", "self": "https://your-domain.atlassian.net/rest/api/2/issueLink/10292", "type": { "id": "10000", "name": "Blocks", "inward": "is blocked by", "outward": "blocks", "self": "https://your-domain.atlassian.net/rest/api/2/issueLinkType/10000" }, "outwardIssue": { "id": "12013", "key": "PU-684", "self": "https://your-domain.atlassian.net/rest/api/2/issue/12013", "fields": { "summary": "a", "status": { "self": "https://your-domain.atlassian.net/rest/api/2/status/10001", "description": "", "iconUrl": "https://your-domain.atlassian.net/", "name": "To Do", "id": "10001", "statusCategory": { "self": "https://your-domain.atlassian.net/rest/api/2/statuscategory/2", "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "priority": { "self": "https://your-domain.atlassian.net/rest/api/2/priority/3", "iconUrl": "https://your-domain.atlassian.net/images/icons/priorities/medium.svg", "name": "Medium", "id": "3" }, "issuetype": { "self": "https://your-domain.atlassian.net/rest/api/2/issuetype/10003", "id": "10003", "description": "A small piece of work that's part of a larger task.", "iconUrl": "https://your-domain.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10316?size=medium", "name": "Sub-task", "subtask": true, "avatarId": 10316, "hierarchyLevel": -1 } } } }, { "id": "10292", "self": "https://your-domain.atlassian.net/rest/api/2/issueLink/10292", "type": { "id": "10000", "name": "Blocks", "inward": "is blocked by", "outward": "blocks", "self": "https://your-domain.atlassian.net/rest/api/2/issueLinkType/10000" }, "outwardIssue": { "id": "12013", "key": "PU-685", "self": "https://your-domain.atlassian.net/rest/api/2/issue/12013", "fields": { "summary": "a", "status": { "self": "https://your-domain.atlassian.net/rest/api/2/status/10001", "description": "", "iconUrl": "https://your-domain.atlassian.net/", "name": "To Do", "id": "10001", "statusCategory": { "self": "https://your-domain.atlassian.net/rest/api/2/statuscategory/2", "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "priority": { "self": "https://your-domain.atlassian.net/rest/api/2/priority/3", "iconUrl": "https://your-domain.atlassian.net/images/icons/priorities/medium.svg", "name": "Medium", "id": "3" }, "issuetype": { "self": "https://your-domain.atlassian.net/rest/api/2/issuetype/10003", "id": "10003", "description": "A small piece of work that's part of a larger task.", "iconUrl": "https://your-domain.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10316?size=medium", "name": "Sub-task", "subtask": true, "avatarId": 10316, "hierarchyLevel": -1 } } } }, { "id": "10292", "self": "https://your-domain.atlassian.net/rest/api/2/issueLink/10292", "type": { "id": "10000", "name": "Blocks", "inward": "is blocked by", "outward": "blocks", "self": "https://your-domain.atlassian.net/rest/api/2/issueLinkType/10000" }, "inwardIssue": { "id": "12013", "key": "PU-677", "self": "https://your-domain.atlassian.net/rest/api/2/issue/12013", "fields": { "summary": "a", "status": { "self": "https://your-domain.atlassian.net/rest/api/2/status/10001", "description": "", "iconUrl": "https://your-domain.atlassian.net/", "name": "To Do", "id": "10001", "statusCategory": { "self": "https://your-domain.atlassian.net/rest/api/2/statuscategory/2", "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "priority": { "self": "https://your-domain.atlassian.net/rest/api/2/priority/3", "iconUrl": "https://your-domain.atlassian.net/images/icons/priorities/medium.svg", "name": "Medium", "id": "3" }, "issuetype": { "self": "https://your-domain.atlassian.net/rest/api/2/issuetype/10003", "id": "10003", "description": "A small piece of work that's part of a larger task.", "iconUrl": "https://your-domain.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10316?size=medium", "name": "Sub-task", "subtask": true, "avatarId": 10316, "hierarchyLevel": -1 } } } } ], "subtasks": [ { "id": "12193", "key": "PU-805", "self": "https://your-domain.atlassian.net/rest/api/3/issue/12193", "fields": { "summary": "one", "status": { "self": "https://your-domain.atlassian.net/rest/api/3/status/10001", "description": "", "iconUrl": "https://your-domain.atlassian.net/", "name": "To Do", "id": "10001", "statusCategory": { "self": "https://your-domain.atlassian.net/rest/api/3/statuscategory/2", "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "priority": { "self": "https://your-domain.atlassian.net/rest/api/3/priority/3", "iconUrl": "https://your-domain.atlassian.net/images/icons/priorities/medium.svg", "name": "Medium", "id": "3" }, "issuetype": { "self": "https://your-domain.atlassian.net/rest/api/3/issuetype/10003", "id": "10003", "description": "A small piece of work that's part of a larger task.", "iconUrl": "https://your-domain.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10316?size=medium", "name": "Sub-task", "subtask": true, "avatarId": 10316, "hierarchyLevel": -1 } } }, { "id": "12194", "key": "PU-806", "self": "https://your-domain.atlassian.net/rest/api/3/issue/12194", "fields": { "summary": "two", "status": { "self": "https://your-domain.atlassian.net/rest/api/3/status/10001", "description": "", "iconUrl": "https://your-domain.atlassian.net/", "name": "To Do", "id": "10001", "statusCategory": { "self": "https://your-domain.atlassian.net/rest/api/3/statuscategory/2", "id": 2, "key": "new", "colorName": "blue-gray", "name": "To Do" } }, "priority": { "self": "https://your-domain.atlassian.net/rest/api/3/priority/3", "iconUrl": "https://your-domain.atlassian.net/images/icons/priorities/medium.svg", "name": "Medium", "id": "3" }, "issuetype": { "self": "https://your-domain.atlassian.net/rest/api/3/issuetype/10015", "id": "10015", "description": "A very small piece of work that's part of a larger task.", "iconUrl": "https://your-domain.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10338?size=medium", "name": "Small Sub-task", "subtask": true, "avatarId": 10338, "hierarchyLevel": -1 } } } ] }, "customfield_10050": { "self": "https://your-domain.atlassian.net/rest/api/3/user?accountId=5fb3d09bf8b01200694cffb1", "accountId": "5fb3d09bf8b01200694cffb1", "avatarUrls": { "48x48": "https://secure.gravatar.com/avatar/29d7f88795ae29f2ce7b66e42005f49?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FU-1.png", "24x24": "https://secure.gravatar.com/avatar/29d7f88795ae29f2ce7b66e42005f49?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FU-1.png", "16x16": "https://secure.gravatar.com/avatar/29d7f88795ae29f2ce7b66e42005f49?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FU-1.png", "32x32": "https://secure.gravatar.com/avatar/29d7f88795ae29f2ce7b66e42005f49?d=https%3A%2F%2Favatar-management--avatars.us-west-2.prod.public.atl-paas.net%2Finitials%2FU-1.png" }, "displayName": "The cutest user", "active": true, "timeZone": "Pacific/Midway", "accountType": "atlassian }, "customfield_10042": 21 }


The following table using the field code Action response details.

What to getJMESPathResult
Issue key%{action.response.key}PU-670
Display name of the creator%{action.response.fields.creator.displayName}Who am I
Atlassian account Id from a single user picker custom field%{action.response.fields.customfield_10050.accountId}5fb3d09bf8b01200694cffb1
Get all labels%{action.response.fields.labels}Backend,Frontend
Get the second label%{action.response.fields.labels[0]}Frontend
Get all sub-tasks%{action.response.subtasks}
{
    "id": "12193",    
    "key": "PU-805",    
    "self": "https://your-domain.atlassian.net/rest/api/3/issue/12193",    
    "fields": {
      "summary": "one",      
      "status": {
        "self": "https://your-domain.atlassian.net/rest/api/3/status/10001",       
        "description": "",        
        "iconUrl": "https://your-domain.atlassian.net/",        
        "name": "To Do",        
        "id": "10001",        
          "statusCategory": { 
            "self": "https://your-domain.atlassian.net/rest/api/3/statuscategory/2",          
            "id": 2,          
           "key": "new",          
            "colorName": "blue-gray",          
            "name": "To Do"        
            }
        },      
      "priority": {
        "self": "https://your-domain.atlassian.net/rest/api/3/priority/3",        
        "iconUrl": "https://your-domain.atlassian.net/images/icons/priorities/medium.svg",        
        "name": "Medium",        
        "id": "3"      
        },      
        "issuetype": {
          "self": "https://your-domain.atlassian.net/rest/api/3/issuetype/10003",        
          "id": "10003",        
          "description": 
          "A small piece of work that's part of a larger task.",        
          "iconUrl": "https://your-domain.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10316?size=medium",        
          "name": "Sub-task",        
          "subtask": true,        
          "avatarId": 10316,        
          "hierarchyLevel": -1      
        }
    }
  },
  {
    "id": "12194",    
    "key": "PU-806",    
    "self": "https://your-domain.atlassian.net/rest/api/3/issue/12194",    
    "fields": {
      "summary": "two",      
      "status": {
        "self": "https://your-domain.atlassian.net/rest/api/3/status/10001",        
        "description": "",        
        "iconUrl": "https://your-domain.atlassian.net/",        
        "name": "To Do",        
        "id": "10001",        
        "statusCategory": {
          "self": "https://your-domain.atlassian.net/rest/api/3/statuscategory/2",          
          "id": 2,          
          "key": "new",          
          "colorName": "blue-gray",          
          "name": "To Do"        
        }
      },     
      "priority": {
        "self": "https://your-domain.atlassian.net/rest/api/3/priority/3",        
        "iconUrl": "https://your-domain.atlassian.net/images/icons/priorities/medium.svg",        
        "name": "Medium",        
        "id": "3"      
        },      
        "issuetype": {
            "self": "https://your-domain.atlassian.net/rest/api/3/issuetype/10015",
            "id": "10015",
            "description": "A very small piece of work that's part of a larger task.",
            "iconUrl": "https://your-domain.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10338?size=medium",
            "name": "Small Sub-task",
            "subtask": true,
            "avatarId": 10338,
            "hierarchyLevel": -1
          }
    }
  }
Get the first sub-task%{action.response.fields.subtasks[0]}
{
    "id": "12193",    
    "key": "PU-805",    
    "self": "https://your-domain.atlassian.net/rest/api/3/issue/12193",    
    "fields": {
      "summary": "one",      
      "status": {
        "self": "https://your-domain.atlassian.net/rest/api/3/status/10001",       
        "description": "",        
        "iconUrl": "https://your-domain.atlassian.net/",        
        "name": "To Do",        
        "id": "10001",        
          "statusCategory": { 
            "self": "https://your-domain.atlassian.net/rest/api/3/statuscategory/2",          
            "id": 2,          
           "key": "new",          
            "colorName": "blue-gray",          
            "name": "To Do"        
            }
        },      
      "priority": {
        "self": "https://your-domain.atlassian.net/rest/api/3/priority/3",        
        "iconUrl": "https://your-domain.atlassian.net/images/icons/priorities/medium.svg",        
        "name": "Medium",        
        "id": "3"      
        },      
        "issuetype": {
          "self": "https://your-domain.atlassian.net/rest/api/3/issuetype/10003",        
          "id": "10003",        
          "description": 
          "A small piece of work that's part of a larger task.",        
          "iconUrl": "https://your-domain.atlassian.net/rest/api/2/universal_avatar/view/type/issuetype/avatar/10316?size=medium",        
          "name": "Sub-task",        
          "subtask": true,        
          "avatarId": 10316,        
          "hierarchyLevel": -1      
        }
    }
  }


Get the names of all fix versions%{action.response.fields.fixVersions[*].name}v2,v5
Get the keys of all linked issues%{action.response.fields.issuelinks[*].*.key[]}

PU-684, PU-685, PU-677

The second * eases the access to all linked issues, independent of the direction (inward or outward). [] flattens the result that otherwise would be list of list.

Filter the sub-tasks by their issuetype and return the sub-task's summary and the status%{action.response.fields.subtasks[?fields.issueType.name == 'Sub-task'].\{"summarySub-task": fields.summary, "statusSub-Task": fields.status.name\}}{"summarySub-task":"one","statusSub-Task":"To Do"}

If you still have questions, feel free to refer to our support team.