> ## Documentation Index
> Fetch the complete documentation index at: https://nango.dev/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# How to set up webhooks with Jira on Nango

> Learn how to receive real-time Jira events in your app using Nango webhooks

Jira Cloud offers two separate ways to get webhooks to your Nango webhook URL: your OAuth app can register a scoped [dynamic webhook](https://developer.atlassian.com/cloud/jira/platform/webhooks/) via the REST API, or a Jira admin can register an admin webhook — either through Jira's admin console UI or its own REST endpoint — which also supports a shared secret for signature verification. This guide covers both.

## How it works

1. When a connection is created, Nango automatically fetches the connected site's URL from Jira's accessible-resources API and stores it as `baseUrl` on the connection — no setup needed on your end for routing.
2. Jira sends a POST request to your Nango webhook URL when a subscribed event occurs.
3. Nango matches the payload's site URL to the correct connection's `baseUrl` and forwards the event to your app.

<Note>
  Jira signs dynamic webhook requests (`/rest/api/3/webhook`) with a bearer JWT in the `Authorization` header, using your app's client secret — Nango doesn't verify this today, so treat your Nango webhook URL as sensitive if you rely on that path. Admin webhooks (registered via `/rest/webhooks/1.0/webhook` or the admin console) are different: you set a shared secret when creating them, and Jira signs requests with HMAC-SHA256 in an `X-Hub-Signature` header. Nango verifies that signature when you set the same value as the **Webhook secret** on the integration in the Nango dashboard.
</Note>

## Setup

### 1. Get your Nango webhook URL

In the Nango dashboard, open your Jira integration and copy the **Webhook URL**.

### 2. Register the webhook in Jira

<Tabs>
  <Tab title="REST API (dynamic webhook)">
    Scoped to your app. Covers issue, comment, issue property, sprint, and version events only, and expires after 30 days.

    1. Add both classic scopes `read:jira-work` and `manage:jira-webhook` in the [Atlassian Developer Console](https://developer.atlassian.com/console/myapps/)'s **Permissions** step, then add them to your Jira integration's **Scopes** field in the Nango dashboard. `manage:jira-webhook` lets your app call the webhook REST API; `read:jira-work` covers the issue, comment, and worklog data behind the events below. See [Jira's webhooks reference](https://developer.atlassian.com/cloud/jira/platform/webhooks/) for the scopes needed by other event categories.

    <Warning>
      You need **both** scopes — `manage:jira-webhook` alone lets you call the endpoint but not read the data behind the events, and registration fails with `401 Unauthorized; scope does not match`. You can check which scopes a connection's token actually has by decoding it and inspecting the `scope` claim.

      Scopes are granted at authorization time. Adding a scope to the integration doesn't add it to connections that already exist — re-authorize the connection (or create a new one) after changing scopes.
    </Warning>

    2. Register the webhook through Nango's proxy. This example subscribes to issue events:

    ```bash theme={null}
    curl -X POST "https://api.nango.dev/proxy/ex/jira/{connectionConfig.cloudId}/rest/api/3/webhook" \
      -H "Authorization: Bearer <NANGO-SECRET-KEY>" \
      -H "Provider-Config-Key: <INTEGRATION-ID>" \
      -H "Connection-Id: <CONNECTION-ID>" \
      -H "Content-Type: application/json" \
      -d '{
        "url": "<NANGO-WEBHOOK-URL>",
        "webhooks": [
          {
            "events": ["jira:issue_created", "jira:issue_updated", "jira:issue_deleted"],
            "jqlFilter": "project = PROJ"
          }
        ]
      }'
    ```

    If the connection's token doesn't have the required scope for an event, Jira rejects the registration for that event. The response returns a `createdWebhookId` for each registered webhook — save these IDs, you'll need them to refresh or delete the webhook.

    3. Refresh the webhook before it expires (30 days after creation, or after your last refresh) using Jira's webhook refresh endpoint with the saved IDs — see [Jira's webhooks reference](https://developer.atlassian.com/cloud/jira/platform/webhooks/) for the exact call. Run this on a schedule, for example from an [action function](/docs/guides/functions/action-functions), or Jira will silently stop sending events.
  </Tab>

  <Tab title="Admin webhook">
    Requires Jira admin permissions on the connected user, independent of your app's OAuth scopes. Covers the full event catalog, including project, board, worklog, attachment, issue link, and user events, and doesn't expire.

    1. In Jira, go to **Settings > System > WebHooks** and create a webhook pointing at your Nango webhook URL, or register one through Nango's proxy against the same endpoint the admin console uses:

    ```bash theme={null}
    curl -X POST "https://api.nango.dev/proxy/ex/jira/{connectionConfig.cloudId}/rest/webhooks/1.0/webhook" \
      -H "Authorization: Bearer <NANGO-SECRET-KEY>" \
      -H "Provider-Config-Key: <INTEGRATION-ID>" \
      -H "Connection-Id: <CONNECTION-ID>" \
      -H "Content-Type: application/json" \
      -d '{
        "name": "My Nango webhook",
        "url": "<NANGO-WEBHOOK-URL>",
        "events": ["jira:issue_created", "jira:issue_updated", "jira:issue_deleted"],
        "secret": "<A-RANDOM-HIGH-ENTROPY-SECRET>"
      }'
    ```

    2. Select the events to subscribe to. A JQL filter is available for a subset of events (mainly issue and issue-property events); sprint and board events ignore it.
    3. Set the same value you used for `secret` as the **Webhook secret** on the Jira integration in the Nango dashboard, so Nango can verify the `X-Hub-Signature` header on incoming deliveries. Jira doesn't let you retrieve the secret again after creation — if you lose it, generate a new one and update both sides.
  </Tab>
</Tabs>

## Handle the webhook

Once routed to a connection, you have two options:

* **Forward it to your app** — Nango forwards the event to your webhook URL with connection attribution. See [External webhook forwarding](/docs/guides/platform/webhook-forwarding).
* **Process it in a sync** — run a sync when the webhook arrives using `webhookSubscriptions` and `onWebhook` in a sync script. See [Real-time syncs](/docs/guides/functions/syncs/realtime-syncs).

## Supported events

Nango can only route events whose payload includes a `self` link on `issue`, `comment`, `sprint`, `board`, `worklog`, `version`, `issueLink`, `project`, `attachment`, `issuetype`, `filter`, or `user`. Examples:

| Event                   | Description                           | Setup path              |
| ----------------------- | ------------------------------------- | ----------------------- |
| `jira:issue_created`    | An issue was created                  | REST API, Admin console |
| `jira:issue_updated`    | An issue was updated                  | REST API, Admin console |
| `jira:issue_deleted`    | An issue was deleted                  | REST API, Admin console |
| `comment_created`       | A comment was added to an issue       | REST API, Admin console |
| `sprint_started`        | A sprint was started                  | REST API, Admin console |
| `jira:version_released` | A version was released                | REST API, Admin console |
| `project_created`       | A project was created                 | Admin console only      |
| `board_updated`         | A board's configuration was changed   | Admin console only      |
| `worklog_created`       | A worklog entry was added to an issue | Admin console only      |
| `attachment_created`    | An attachment was added to an issue   | Admin console only      |

For the full list, see [Jira's webhook events reference](https://developer.atlassian.com/cloud/jira/platform/webhooks/).

<Tip>Need help getting started? Join us in the [community](https://nango.dev/slack).</Tip>
