Forums

Articles
Create
cancel
Showing results for 
Search instead for 
Did you mean: 

What native Jira Cloud webhooks can't do

Disclosure: I'm part of the team at UX Software. We build Webhooks Pro for Jira Cloud, so we've spent a long time in this particular corner of the platform. This article is about the platform behaviour first — I've tried to be accurate about what native webhooks actually do, including the parts people underestimate.

Every few weeks someone posts a variation of the same question here: "my Jira webhook isn't working", "can I change what Jira sends?", "how do I know if it was delivered?"

The answers usually jump straight to "use an app". I'd rather start one level down, because a lot of the frustration comes from not knowing exactly where the native feature stops. So: here's an honest map.

First, what native Jira Cloud webhooks already do

This part gets skipped a lot, including by vendors. Native webhooks are more capable than their reputation suggests:

  • JQL filtering per webhook. You can scope an issue webhook to project = OPS AND priority = High and only matching issues fire it. This is built in.
  • HMAC signing. Set a secret and Jira sends an X-Hub-Signature header so your receiver can verify the request really came from Jira.
  • An admin UI. System → WebHooks. No API calls required.
  • Workflow post function support. You can fire a webhook from a specific transition.
  • No expiry. Webhooks you configure in the admin UI don't expire. (The 30-day refresh requirement people bring up applies to webhooks registered dynamically through the API by Connect/Forge apps — a different thing.)
  • Broad event coverage. Issue created/updated/deleted, the full comment lifecycle, worklogs, attachments, projects, versions, sprints. Most of what you'd reach for is there.

If your integration needs "when a high-priority bug is created in OPS, POST it to this URL, signed" — native does that, and you should just use native.

The wall shows up somewhere else.

1. You get Jira's payload, not yours

Native webhooks send a Jira-defined JSON body, over POST, to your URL. That's the whole contract. No method choice, no body shaping, no custom headers, no query parameters.

That's fine when you control the receiver. It stops being fine the moment the receiver is something you don't control and that expects its own shape — Slack, Teams, PagerDuty, a partner's API, an internal service with a strict schema.

2026-08-09 16_53_30-Webhooks-core.jpg.png

Choosing the method, the body, the headers and the query parameters per webhook.

What you end up building: a small middleman service whose entire job is to accept Jira's payload, reshape it, and forward it. Now you're operating a service, with its own hosting, secrets, uptime and on-call, so that a JSON object can change shape.

I've seen a lot of these. They're the single most common piece of accidental infrastructure around Jira.

2. Fire and forget: no delivery visibility

This is the big one, and it's the reason most "my webhook isn't working" threads are hard to answer.

Native webhooks give you no delivery log. When something doesn't arrive downstream, you can't tell from the Jira side whether:

  • the event never matched your JQL filter,
  • Jira fired and the receiver returned 500,
  • Jira fired and the receiver returned 200 but silently dropped it,
  • DNS failed, TLS failed, or the request timed out,
  • the receiver was fine and the problem is three hops further downstream.

From inside Jira, all five look identical. So debugging turns into instrumenting the receiver and waiting for the problem to happen again — which, if it's intermittent, can take days.

Webhook-Logs-&-Replay.jpg

The same five cases, told apart: a 500 next to a 409 next to a replayed 503, and the receiver's own error body sitting beside the request that caused it.

What you end up building: request logging on the receiver, which only helps for requests that actually reached the receiver. The failures you most need to see are exactly the ones that don't show up there.

This gap is tracked as https://jira.atlassian.com/browse/JRACLOUD-41463 «Webhook logging for Jira» — open since 2014, 450+ votes, still Gathering Interest.

3. When a delivery fails, it's gone

Your receiver was down for twenty minutes during a deploy. Jira fired forty events at it. Those forty events are not coming back.

There's no queue you can drain, no "replay the last hour" button, no record of what was missed. If those events mattered — a compliance sink, a downstream ticket sync, a billing hook — you're reconstructing them by hand from Jira's history and hoping you got the set right.

What you end up building: a durable queue in front of your receiver, so your infrastructure holds the events even when your service is down. Reasonable engineering, but it's real infrastructure you now own for the life of the integration.

Atlassian’s failed-webhook API (GET /rest/api/3/webhook/failed) sometimes gets suggested here, but it doesn’t help site admins: it’s scoped to the requesting Connect app, and a failure may stop being returned after 72 hours. It has no relation to webhooks configured under System → WebHooks.

4. Event storms

Someone bulk-edits 300 issues. Someone drags an issue across a board and Jira emits several updates in a second. An automation rule touches every issue in a sprint.

Native webhooks fire per event, faithfully. Your receiver gets all of it. If the receiver is a Slack channel, a human is now getting a wall of near-identical notifications. If it's a rate-limited API, you're getting 429s and losing deliveries anyway.

What you end up building: debouncing or coalescing logic on the receiver, keyed by entity, with a time window. Not hard, but it's the third piece of infrastructure in this article and they all compound.

5. Some events simply aren't there

Native coverage is broad but not complete. Eight that come up regularly and don't exist as native webhook events:

  • Issue Assigned
  • Issue Mentioned
  • Comment Mentioned
  • Version Archived
  • Version Unarchived
  • Component Created
  • Component Updated
  • Component Deleted

"Notify the on-call channel when someone is @-mentioned" and "sync our component list to the service catalogue" both sound trivial and both run straight into this.

2026-08-09 16_51_06-Webhooks-core.jpg.png

Issue Assigned, Issue Mentioned and Comment Mentioned as ordinary checkboxes, alongside the JQL filter.

What you end up building: polling. A scheduled job hitting the REST API on an interval, diffing state, inferring the event that the platform didn't tell you about. This is the worst of the workarounds — it's laggy, it burns API quota, and diffing logic is where subtle bugs live.

A related gap: nothing is time-based

Native webhooks are event-driven only. There's no "fire this every weekday at 09:00" — so a daily digest, a nightly reconciliation ping, or a scheduled health check to a downstream system needs an external scheduler holding Jira credentials.

How we thought about it

We built Webhooks Pro because those five workarounds kept showing up as the same five workarounds, rebuilt separately at every organisation, each one a small permanent operational tax.

The design goal was to move all of it inside Jira, so there's nothing to host:

  • Request shaping — choose the HTTP method, and define the body yourself. Either pick fields, or write the exact JSON with {{issue.key}}-style placeholders. Custom headers and URL parameters too.

Payload-Templates.jpg

  • Delivery logs — every attempt recorded with status code, request, and the response body the receiver sent back. When a delivery fails, you can see what the receiver said. Retention is configurable, 14 days by default.
  • Replay — one-click or bulk re-send from the log. Worth being precise here: we deliberately do not auto-retry. Each event produces exactly one attempt, so a flaky receiver never gets amplified behind your back. You look at the log, decide what's worth re-sending, and re-send it.
  • Debounce — rapid events on the same entity collapse into one delivery. The 300-issue bulk edit stops being 300 notifications.
  • Auto-disable — after N consecutive failures a webhook can flip itself off to protect a receiver that's clearly down. Off by default, because aggressive auto-disable causes its own problems.
  • Schedules — cron-based delivery for the time-based cases.
  • The eight missing events above, as first-class triggers.

Two ways to define the body: map Jira fields to keys, or write the JSON yourself.

It's a Forge app, so it runs on Atlassian infrastructure — no external service in the path.

Listing here if you want to look: Webhooks Pro on the Atlassian Marketplace

FAQ

Should I just use native?
If your receiver accepts Jira's payload as-is and you'd notice quickly when it breaks, yes. Native is genuinely good at that job and there's no reason to add anything.

Doesn't Jira Automation already do webhooks?
It sends web requests, yes, and for simple cases it's a good answer. Where it gets awkward is volume-heavy integrations and diagnosis — you're inside the automation audit log rather than looking at a delivery-level record of what was sent and what came back.

Why no auto-retry?
Predictability. Auto-retry means a receiver having a bad minute gets hit three times as hard, and you can't tell from the receiver's logs how many times it was actually called. Manual replay keeps the delivery count honest and puts the decision with the person who can see why it failed.

Does this replace my queue?
No, and I'd be careful with anyone who says otherwise. If delivery is business-critical, the receiver should still be idempotent and durable. Logs and replay shorten the recovery, they don't remove the need for the receiver to be built properly.


If you've hit one of these walls, I'd genuinely like to hear which one and what you built around it — the workarounds people come up with are usually more interesting than the gap itself.

2 comments

Mia Tamm _Simpleasyty_
Atlassian Partner
August 12, 2026

Really useful breakdown, especially because webhooks often look simple until you start relying on them for something important in production.

The points around delivery visibility and retries really stood out to me. When something fails silently, debugging quickly becomes much harder than the original integration itself.

I also liked that you included the “event storm” side of the problem — that’s one of those things that is easy to underestimate at the beginning.

Great post, @Denys Aleksieienko _UX Software_. Very practical and easy to follow.

Denys Aleksieienko _UX Software_
Atlassian Partner
August 12, 2026

Thanks so much, @Mia Tamm _Simpleasyty_ - really appreciate you reading it and taking the time to reply. That means a lot coming from another partner in the spac

The delivery-visibility point is the one that kept coming back for us too - hard to overstate how much it changes debugging once the delivery record lives on the Jira side rather than only on the receiver. Glad it resonated 🙂

Always happy to swap notes with folks building in adjacent spaces.

 

Like Mia Tamm _Simpleasyty_ likes this

Comment

Log in or Sign up to comment
TAGS
AUG Leaders

Atlassian Community Events