A webhook is a user-defined callback over HTTP. You can use Jira webhooks to notify your app or web application when certain events occur in Jira. For example, you might want to alert your remote application when an issue is updated or when sprint is started. Using a webhook to do this means that your remote application doesn't have to periodically poll Jira (via the REST APIs) to determine whether changes have occurred.
A webhook in Jira is defined by the following information that you need to provide when registering (that is, creating) a new webhook:
A simple webhook might look like this:
Name: "My simple webhook"
URL: www.myremoteapp.com/webhookreceiver
Scope: all issues
Events: all issue events
A more complex webhook might look like this:
Name: "A slightly more advanced webhook"
URL: www.myremoteapp.com/webhookreceiver
Scope: Project = JRA AND fixVersion IN ("6.4", "7.0")
Events: Issue Updated, Issue Created
To register a webhook, you can use any of the following methods:
NOTE In Jira 10+ the url to webhook resource has changed to
<JIRA_URL>/rest/jira-webhook/1.0/webhook
To register a webhook via REST, execute POST in JSON format to the following URL:
<JIRA_URL>/rest/webhooks/1.0/webhook
1 2{ "name": "my first webhook via rest", "url": "http://www.example.com/webhooks", "events": [ "jira:issue_created", "jira:issue_updated" ], "filters": { "issue-related-events-section": "Project = JRA AND resolution = Fixed" }, "excludeBody" : false }
The response will return the webhook in JSON with additional information, including the user that created the webhook, the created timestamp, etc.
To unregister (that is, delete) a webhook via REST, execute DELETE to the following URL:
<JIRA_URL>/rest/webhooks/1.0/webhook/{id of the webhook}
The following would delete the webhook with an ID of 70:
1 2curl --user username:password -X DELETE -H "Content-Type: application/json" <JIRA_URL>/rest/webhooks/1.0/webhook/70
To query a webhook via REST:
<JIRA_URL>/rest/webhooks/1.0/webhook.
1 2curl --user username:password -X GET -H "Content-Type: application/json" <JIRA_URL>/rest/webhooks/1.0/webhook
<JIRA_URL>/rest/webhooks/1.0/webhook/<webhook ID>
The following would get a webhook with an ID of 72:
1 2curl --user username:password -X GET -H "Content-Type: application/json" <JIRA_URL>/rest/webhooks/1.0/webhook/72
To edit a webhook, execute PUT method to the following URL:
<JIRA_URL>/rest/webhooks/1.0/webhook/{id of the webhook}
1 2{ "name": "my first webhook via rest", "url": "http://www.example.com/webhooks", "events": [ "jira:issue_created", "jira:issue_updated" ], "filters": { "issue-related-events-section": "Project = JRA AND resolution = Fixed" }, "excludeBody" : false }
The information in this section will help you configure a webhook, whether you create a new one or modify an existing one.
The following events are available for Jira webhooks.
The string in parentheses is the name of the webhookEvent
in the response.
Issue related:
Issue...
Note: This event fires if a worklog is updated or deleted
Issue link...
Note: Available in Jira 7.5 and later.
Worklog...
Comment...
Note: Available in Jira 7.1, or later.
Project-related:
Project...
Version...
Note: The delete event contains information about merged versions.
User-related:
Jira configuration-related:
Jira Software-related:
If you are unsure which events to register your webhook for, then the simplest approach is to register your webhook for all events for the relevant entity (for example, all issue-related events). Then you won't need to update the webhook if you need to handle these events in future; you can just add code in your app or web application when you want to react to them.
If you only want your webhook events to fire for a specific set of issues, you can specify a JQL query in your webhook to send only events triggered by matching issues. For example, using JQL you could register for all Issue Deleted events on issues in the Test ("TEST") project, which are marked with ‘Performance’ component.
Although the JQL that uses standard Jira fields is very performant, some custom fields, because of their implementation, can take multiple seconds to query. You should take this into account when using JQL for a webhook, as the query will be run with each event.
You can add variables to the webhook URL when creating or updating a webhook. The variables are the following:
${board.id}
${issue.id}
${issue.key}
${mergedVersion.id}
${modifiedUser.key}
${modifiedUser.name}
${project.id}
${project.key}
${sprint.id}
${version.id}
You can use these variables to dynamically insert the value of the current issue key, sprint ID, project key, and so on, into the webhook URL when it is triggered.
For example, you specified the URL for your webhook with the ${issue.key}
variable, like this:
1 2http://jira.example.com/webhook/${issue.key}
If an issue with the key EXA-1 triggers a webhook, then the URL that will be used is:
1 2http://service.example.com/webhook/EXA-1
Webhooks can be attached as a workflow post function. This makes it easy to trigger a webhook when an issue makes a workflow transition. For instance, when it gets rejected from QA or when it gets resolved.
To add a webhook as a post function to a workflow:
Notes:
Webhooks will be run without a specific user context. For example, all issues will be available to the webhook,
rather than having them scoped to a single user. (Note the URL will also contain user parameters in the form ?user_id=(u'sysadmin',)&user_key=(u'sysadmin',)
appended at the end.)
By default, a webhook will send a request with a JSON callback when it is triggered. If you don't want the JSON body to be sent, then you need to select Exclude body when configuring the webhook.
At a high level, every callback contains the webhookEvent
ID, the timestamp
, and information about the entity
associated with the event (for example, issue, project, board, and so on). Callbacks may have additional information, depending
on the type of event associated with it. As an example, the structure of a callback for an issue-related event
is described next.
A callback for an issue-related event is structured like this:
1 2{ "timestamp" "event" "user": { --> See User shape in table below }, "issue": { --> See Issue shape in table below }, "changelog" : { --> See Changelog shape in table below }, "comment" : { --> See Comment shape in table below } }
Issue shape |
|
User shape |
|
Changelog shape |
|
Comment shape |
|
1 2{ "id": 2, "timestamp": 1525698237764, "issue": { "id":"99291", "self":"https://jira.atlassian.com/rest/api/2/issue/99291", "key":"JRA-20002", "fields":{ "summary":"I feel the need for speed", "created":"2009-12-16T23:46:10.612-0600", "description":"Make the issue nav load 10x faster", "labels":["UI", "dialogue", "move"], "priority": "Minor" } }, "user": { "self":"https://jira.atlassian.com/rest/api/2/user?username=brollins", "name":"brollins", "key":"brollins", "emailAddress":"bryansemail at atlassian dot com", "avatarUrls":{ "16x16":"https://jira.atlassian.com/secure/useravatar?size=small&avatarId=10605", "48x48":"https://jira.atlassian.com/secure/useravatar?avatarId=10605" }, "displayName":"Bryan Rollins [Atlassian]", "active" : "true" }, "changelog": { "items": [ { "toString": "A new summary.", "to": null, "fromString": "What is going on here?????", "from": null, "fieldtype": "jira", "field": "summary" }, { "toString": "New Feature", "to": "2", "fromString": "Improvement", "from": "4", "fieldtype": "jira", "field": "issuetype" } ], "id": 10124 }, "comment" : { "self":"https://jira.atlassian.com/rest/api/2/issue/10148/comment/252789", "id":"252789", "author":{ "self":"https://jira.atlassian.com/rest/api/2/user?username=brollins", "name":"brollins", "emailAddress":"bryansemail@atlassian.com", "avatarUrls":{ "16x16":"https://jira.atlassian.com/secure/useravatar?size=small&avatarId=10605", "48x48":"https://jira.atlassian.com/secure/useravatar?avatarId=10605" }, "displayName":"Bryan Rollins [Atlassian]", "active":true }, "body":"Just in time for AtlasCamp!", "updateAuthor":{ "self":"https://jira.atlassian.com/rest/api/2/user?username=brollins", "name":"brollins", "emailAddress":"brollins@atlassian.com", "avatarUrls":{ "16x16":"https://jira.atlassian.com/secure/useravatar?size=small&avatarId=10605", "48x48":"https://jira.atlassian.com/secure/useravatar?avatarId=10605" }, "displayName":"Bryan Rollins [Atlassian]", "active":true }, "created":"2011-06-07T10:31:26.805-0500", "updated":"2011-06-07T10:31:26.805-0500" }, "webhookEvent": "jira:issue_updated" }
If a webhook is triggered successfully, a response code of 200 is returned. All other response codes should be treated as an unsuccessful attempt to trigger the webhook.
In this case, Jira will log an error in the log file atlassian-jira.log
.
Currently there is a bug which makes Jira behave differently. You can watch JRASERVER-41388 issue for updates.
Jira 5.2 and later support webhooks. If you use Jira 5.2.x, keep in mind the following limitations:
If you use Jira 5.2.1 or earlier, there are two known issues and limitations when using JQL with webhooks:
currentUser()
function does not work as expected.
If a JQL query filters for a field that changes frequently, it may not return the desired results (for a description of this issue, see the 5.2 Upgrade Notes). This means that you should not write a webhook that uses the JQL expression to look for a specific state change.
For example, if you want to POST a webhook anytime an issue is changed to have a Priority of Blocker, you should not include "Priority = Blocker" in the JQL clause, but leave out priority, and filter for those events where Priority was changed to Blocker on the receiving side of the webhook.
If you use Jira 5.2.2 or earlier, there is a known issues when using JQL with webhooks:
${issue.key}
variable replacement does not work in a webhook, when the webhook is used in a workflow
post function. Note that the ${issue.key}
variable replacement does work when an issue event triggers the webhook.Atlassian blog posts:
Rate this page: