How to set up webhooks with Jira on Tenklo

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

Jira Cloud offers two separate ways to get webhooks to your Tenklo webhook URL: your OAuth app can register a scoped dynamic webhook 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, Tenklo 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 Tenklo webhook URL when a subscribed event occurs.
  3. Tenklo matches the payload's site URL to the correct connection's baseUrl and forwards the event to your app.

Jira signs dynamic webhook requests (/rest/api/3/webhook) with a bearer JWT in the Authorization header, using your app's client secret — Tenklo doesn't verify this today, so treat your Tenklo 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. Tenklo verifies that signature when you set the same value as the Webhook secret on the integration in the Tenklo dashboard.

Setup

1. Get your Tenklo webhook URL

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

2. Register the webhook in Jira

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's Permissions step, then add them to your Jira integration's Scopes field in the Tenklo 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 for the scopes needed by other event categories.

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.

  1. Register the webhook through Tenklo's proxy. This example subscribes to issue events:
curl -X POST "https://api.tenklo.dev/proxy/ex/jira/{connectionConfig.cloudId}/rest/api/3/webhook" \
  -H "Authorization: Bearer <NANGO-API-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.

  1. 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 for the exact call. Run this on a schedule, for example from an action function, or Jira will silently stop sending events.

Handle the webhook

Once routed to a connection, you have two options:

  • Forward it to your app — Tenklo forwards the event to your webhook URL with connection attribution. See External 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.

Supported events

Tenklo 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:

EventDescriptionSetup path
jira:issue_createdAn issue was createdREST API, Admin console
jira:issue_updatedAn issue was updatedREST API, Admin console
jira:issue_deletedAn issue was deletedREST API, Admin console
comment_createdA comment was added to an issueREST API, Admin console
sprint_startedA sprint was startedREST API, Admin console
jira:version_releasedA version was releasedREST API, Admin console
project_createdA project was createdAdmin console only
board_updatedA board's configuration was changedAdmin console only
worklog_createdA worklog entry was added to an issueAdmin console only
attachment_createdAn attachment was added to an issueAdmin console only

For the full list, see Jira's webhook events reference.

Need help getting started? Join us in the community.

On this page