A webhook is a user-defined callback over HTTP. You can use JIRA webhooks to notify your add-on or web application when certain events occur in JIRA. For example, you might want to alert your remote application when an issue has been updated or when sprint has been 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, which you need to provide when registering (i.e. creating) a new webhook:
A simple webhook might look like this:
Name: "My simple webhook"**
URL**: http://www.myremoteapplication.com/webhookreceiver
Scope: all issues
Events: all issue events
A more complex webhook might look like this:
Name: "A slightly more advanced webhook" URL: http://www.myremoteapplication.com/webhookreceiver** Scope:** Project = JRA AND fixVersion IN ("6.4", "7.0") Events: Issue Updated, Issue Created
To register (i.e. create) a webhook, you can use any of the following methods:
To register a webhook via REST:
POST a webhook in JSON format to: `<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" ], "jqlFilter": "Project = JRA AND resolution = Fixed", "excludeIssueDetails" : 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 (i.e. delete) a webhook via REST:
Execute a 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:
To get all webhooks for a JIRA instance, perform a GET with the following URL: <JIRA_URL>/rest/webhooks/1.0/webhook.
1 2curl --user username:password -X GET -H "Content-Type: application/json" http://jira.example.com/rest/webhooks/1.0/webhook
To get a specific webhook by its ID, perform a GET with the following URL: <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" http://jira.example.com/rest/webhooks/1.0/webhook/72
The information in this section will help you configure a webhook, whether you are creating a new one or modifying 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:
Note, worklogs and comments will soon be removed from callbacks for issue-related events. The jira:worklog_updated event has also been deprecated. See the notice.
Note, callbacks for 'worklog' events will soon be restricted to only include the 100 most recent items. See the notice.
Project-related:
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 (e.g. 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 add-on or web application once 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, you could register for all Issue Deleted events on issues in the Test ("TEST") Project with the 'Performance' component.
Note, 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 append variables to the webhook URL when creating or updating a webhook. The variables are listed below:
${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, etc, into the webhook URL when it is triggered. Consider the following example:
Say 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, e.g. 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 sent, then you will 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 (e.g. issue, project, board, etc). 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 below:
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 |
|
You can see a full example of this below. This JSON callback shows an update to an issue (some fields changed value) where a comment was also added:
{
1 2"id": 2, "timestamp": "2009-09-09T00:08:36.796-0500", "issue": { "expand":"renderedFields,names,schema,transitions,operations,editmeta,changelog", "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", "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" }, "timestamp": "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.
JIRA will retry sending three times, and then log an error in the log file: atlassian-jira.log. For JIRA Cloud customers, who don't have access to log files, we are investigating a way to provide more visibility into any webhook errors.
JIRA 5.2 and later support webhooks. If you are using JIRA 5.2.x, be aware of the following limitations:
If you are using JIRA 5.2.1 or earlier, there are two known issues/limitations when using JQL with webhooks:
currentUser() function does not work as expected.
A JQL query may not return the desired results, if it is filtering for a field that changes frequently (see the 5.2 Upgrade Notes for a description of this issue). This means that you should not write a webhook which uses the JQL expression to look for a specific state change.
For example, if you wanted to POST a webhook anytime an issue was 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 are using 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, the ${issue.key} variable replacement does work when an issue event triggers the webhook.Atlassian blog posts:
Rate this page: