[{"data":1,"prerenderedAt":1059},["ShallowReactive",2],{"content-query-ILppYu0A6a":3},{"_path":4,"_dir":5,"_draft":6,"_partial":6,"_locale":7,"title":8,"description":9,"layout":10,"author":11,"tags":12,"categories":17,"date":19,"faq":20,"image":33,"body":34,"_type":1052,"_id":1053,"_source":1054,"_file":1055,"_stem":1056,"_extension":1057,"sitemap":1058},"/blog/jira-webhooks-guide","blog",false,"","Jira Webhooks: Setup, Payload and Security","How to set up Jira webhooks — admin UI vs REST API, JQL filters, the payload format, X-Hub-Signature verification and testing. A complete, practical guide.","post","Karolis Rusenas",[13,14,15,16],"jira","atlassian","webhooks","guide",[18],"tutorials","2026-07-07 10:00:00",[21,24,27,30],{"q":22,"a":23},"How do I create a webhook in Jira?","Two ways. In the admin UI: Settings → System → Webhooks → Create a WebHook, then set a URL, pick events and optionally a JQL filter. Or via the REST API (POST /rest/api/3/webhook), which creates a dynamic webhook that supports a signing secret. The admin UI path needs Jira admin rights; the REST path registers webhooks on behalf of an OAuth 2.0/Connect app.",{"q":25,"a":26},"What does a Jira webhook payload look like?","JSON with a webhookEvent field naming the event (e.g. jira:issue_updated), a timestamp, the user who triggered it, the affected issue (key, fields like summary, status, priority, assignee), and — for updates — a changelog listing exactly which fields changed from what to what.",{"q":28,"a":29},"Are Jira webhooks signed?","Only dynamic webhooks registered through the REST API with a secret are signed — HMAC-SHA256 of the body in the X-Hub-Signature header. Webhooks created in the admin UI are not signed: secure them with a hard-to-guess token in the URL and/or by allowlisting Atlassian IP ranges.",{"q":31,"a":32},"Why is my Jira webhook not firing?","The usual suspects: the JQL filter does not match the issue, the event type was not selected, the endpoint returned a non-2xx and deliveries are failing, or (on Cloud) the URL is not reachable from the public internet. Point the webhook at a request bin first to confirm Jira is sending at all, then narrow it down.","/images/blog/heroes/route.jpg",{"type":35,"children":36,"toc":1043},"root",[37,47,61,84,91,115,140,160,166,171,190,195,201,214,628,633,719,747,753,758,843,849,861,895,908,914,919,973,979,1037],{"type":38,"tag":39,"props":40,"children":41},"element","p",{},[42],{"type":38,"tag":43,"props":44,"children":46},"img",{"alt":45,"src":33},"Jira webhooks guide",[],{"type":38,"tag":39,"props":48,"children":49},{},[50,53,59],{"type":51,"value":52},"text","Jira can notify your code the moment an issue is created, updated, transitioned or commented on. That is what ",{"type":38,"tag":54,"props":55,"children":56},"strong",{},[57],{"type":51,"value":58},"Jira webhooks",{"type":51,"value":60}," are: HTTP POSTs that Jira Cloud (or Data Center) sends to a URL you choose, carrying the issue as JSON. This guide covers the parts people actually get stuck on — the two ways to register a webhook, JQL filtering, what the payload really contains, and how to secure and test the whole thing.",{"type":38,"tag":39,"props":62,"children":63},{},[64,66,73,75,82],{"type":51,"value":65},"If your immediate goal is receiving Jira events on ",{"type":38,"tag":67,"props":68,"children":70},"code",{"className":69},[],[71],{"type":51,"value":72},"localhost",{"type":51,"value":74},", we have a focused walkthrough for that: ",{"type":38,"tag":76,"props":77,"children":79},"a",{"href":78},"/blog/receive-jira-webhooks-locally",[80],{"type":51,"value":81},"Test Jira webhooks locally",{"type":51,"value":83},". This guide is the broader reference.",{"type":38,"tag":85,"props":86,"children":88},"h2",{"id":87},"two-ways-to-register-a-jira-webhook",[89],{"type":51,"value":90},"Two ways to register a Jira webhook",{"type":38,"tag":39,"props":92,"children":93},{},[94,99,101,106,108,113],{"type":38,"tag":54,"props":95,"children":96},{},[97],{"type":51,"value":98},"1. The admin UI (classic webhooks).",{"type":51,"value":100}," Go to ",{"type":38,"tag":54,"props":102,"children":103},{},[104],{"type":51,"value":105},"Settings → System → Webhooks → Create a WebHook",{"type":51,"value":107},". You give it a name, a URL, select events (issue created/updated/deleted, comment events, project/version/user events, and more) and optionally a JQL filter. This is the fastest path and fine for internal tooling — but these webhooks are ",{"type":38,"tag":54,"props":109,"children":110},{},[111],{"type":51,"value":112},"not signed",{"type":51,"value":114},", and they are instance-wide, so you need Jira admin rights.",{"type":38,"tag":39,"props":116,"children":117},{},[118,123,125,131,133,138],{"type":38,"tag":54,"props":119,"children":120},{},[121],{"type":51,"value":122},"2. The REST API (dynamic webhooks).",{"type":51,"value":124}," Apps using OAuth 2.0 or Connect register webhooks with ",{"type":38,"tag":67,"props":126,"children":128},{"className":127},[],[129],{"type":51,"value":130},"POST /rest/api/3/webhook",{"type":51,"value":132},". Dynamic webhooks support a ",{"type":38,"tag":54,"props":134,"children":135},{},[136],{"type":51,"value":137},"signing secret",{"type":51,"value":139}," (verification below), are scoped to the app that created them, and expire — Jira Cloud requires apps to refresh them periodically (they last 30 days unless extended), so schedule a refresh job.",{"type":38,"tag":39,"props":141,"children":142},{},[143,145,150,152,158],{"type":51,"value":144},"There is a third, often-overlooked option: ",{"type":38,"tag":54,"props":146,"children":147},{},[148],{"type":51,"value":149},"Automation rules",{"type":51,"value":151},". Jira's automation can fire a \"Send web request\" action on any rule trigger, which behaves like a webhook with full control over method, headers and body. If you need custom headers (say, an ",{"type":38,"tag":67,"props":153,"children":155},{"className":154},[],[156],{"type":51,"value":157},"Authorization",{"type":51,"value":159}," token) this is the easiest way to get them — classic webhooks send no custom headers.",{"type":38,"tag":85,"props":161,"children":163},{"id":162},"scope-deliveries-with-jql",[164],{"type":51,"value":165},"Scope deliveries with JQL",{"type":38,"tag":39,"props":167,"children":168},{},[169],{"type":51,"value":170},"A webhook without a filter receives events for the whole instance. Add a JQL filter at registration time to narrow it:",{"type":38,"tag":172,"props":173,"children":176},"pre",{"className":174,"code":175,"language":51,"meta":7,"style":7},"language-text shiki shiki-themes github-dark","project = PROJ AND issuetype = Bug\n",[177],{"type":38,"tag":67,"props":178,"children":179},{"__ignoreMap":7},[180],{"type":38,"tag":181,"props":182,"children":185},"span",{"class":183,"line":184},"line",1,[186],{"type":38,"tag":181,"props":187,"children":188},{},[189],{"type":51,"value":175},{"type":38,"tag":39,"props":191,"children":192},{},[193],{"type":51,"value":194},"Only events for matching issues are delivered. This is the single best lever for keeping your handler simple — filter in Jira, not in code.",{"type":38,"tag":85,"props":196,"children":198},{"id":197},"the-payload",[199],{"type":51,"value":200},"The payload",{"type":38,"tag":39,"props":202,"children":203},{},[204,206,212],{"type":51,"value":205},"Every delivery is JSON with a ",{"type":38,"tag":67,"props":207,"children":209},{"className":208},[],[210],{"type":51,"value":211},"webhookEvent",{"type":51,"value":213}," field. An issue update looks like this (trimmed):",{"type":38,"tag":172,"props":215,"children":219},{"className":216,"code":217,"language":218,"meta":7,"style":7},"language-json shiki shiki-themes github-dark","{\n  \"timestamp\": 1768471800000,\n  \"webhookEvent\": \"jira:issue_updated\",\n  \"user\": { \"accountId\": \"5f00...aa\", \"displayName\": \"Alex Doe\" },\n  \"issue\": {\n    \"key\": \"PROJ-42\",\n    \"fields\": {\n      \"summary\": \"Checkout button unresponsive on mobile\",\n      \"status\": { \"name\": \"In Progress\" },\n      \"priority\": { \"name\": \"High\" },\n      \"assignee\": { \"displayName\": \"Alex Doe\" }\n    }\n  },\n  \"changelog\": {\n    \"items\": [\n      { \"field\": \"status\", \"fromString\": \"To Do\", \"toString\": \"In Progress\" }\n    ]\n  }\n}\n","json",[220],{"type":38,"tag":67,"props":221,"children":222},{"__ignoreMap":7},[223,232,257,280,332,346,368,381,403,434,464,494,503,512,525,539,601,610,619],{"type":38,"tag":181,"props":224,"children":225},{"class":183,"line":184},[226],{"type":38,"tag":181,"props":227,"children":229},{"style":228},"--shiki-default:#E1E4E8",[230],{"type":51,"value":231},"{\n",{"type":38,"tag":181,"props":233,"children":235},{"class":183,"line":234},2,[236,242,247,252],{"type":38,"tag":181,"props":237,"children":239},{"style":238},"--shiki-default:#79B8FF",[240],{"type":51,"value":241},"  \"timestamp\"",{"type":38,"tag":181,"props":243,"children":244},{"style":228},[245],{"type":51,"value":246},": ",{"type":38,"tag":181,"props":248,"children":249},{"style":238},[250],{"type":51,"value":251},"1768471800000",{"type":38,"tag":181,"props":253,"children":254},{"style":228},[255],{"type":51,"value":256},",\n",{"type":38,"tag":181,"props":258,"children":260},{"class":183,"line":259},3,[261,266,270,276],{"type":38,"tag":181,"props":262,"children":263},{"style":238},[264],{"type":51,"value":265},"  \"webhookEvent\"",{"type":38,"tag":181,"props":267,"children":268},{"style":228},[269],{"type":51,"value":246},{"type":38,"tag":181,"props":271,"children":273},{"style":272},"--shiki-default:#9ECBFF",[274],{"type":51,"value":275},"\"jira:issue_updated\"",{"type":38,"tag":181,"props":277,"children":278},{"style":228},[279],{"type":51,"value":256},{"type":38,"tag":181,"props":281,"children":283},{"class":183,"line":282},4,[284,289,294,299,303,308,313,318,322,327],{"type":38,"tag":181,"props":285,"children":286},{"style":238},[287],{"type":51,"value":288},"  \"user\"",{"type":38,"tag":181,"props":290,"children":291},{"style":228},[292],{"type":51,"value":293},": { ",{"type":38,"tag":181,"props":295,"children":296},{"style":238},[297],{"type":51,"value":298},"\"accountId\"",{"type":38,"tag":181,"props":300,"children":301},{"style":228},[302],{"type":51,"value":246},{"type":38,"tag":181,"props":304,"children":305},{"style":272},[306],{"type":51,"value":307},"\"5f00...aa\"",{"type":38,"tag":181,"props":309,"children":310},{"style":228},[311],{"type":51,"value":312},", ",{"type":38,"tag":181,"props":314,"children":315},{"style":238},[316],{"type":51,"value":317},"\"displayName\"",{"type":38,"tag":181,"props":319,"children":320},{"style":228},[321],{"type":51,"value":246},{"type":38,"tag":181,"props":323,"children":324},{"style":272},[325],{"type":51,"value":326},"\"Alex Doe\"",{"type":38,"tag":181,"props":328,"children":329},{"style":228},[330],{"type":51,"value":331}," },\n",{"type":38,"tag":181,"props":333,"children":335},{"class":183,"line":334},5,[336,341],{"type":38,"tag":181,"props":337,"children":338},{"style":238},[339],{"type":51,"value":340},"  \"issue\"",{"type":38,"tag":181,"props":342,"children":343},{"style":228},[344],{"type":51,"value":345},": {\n",{"type":38,"tag":181,"props":347,"children":349},{"class":183,"line":348},6,[350,355,359,364],{"type":38,"tag":181,"props":351,"children":352},{"style":238},[353],{"type":51,"value":354},"    \"key\"",{"type":38,"tag":181,"props":356,"children":357},{"style":228},[358],{"type":51,"value":246},{"type":38,"tag":181,"props":360,"children":361},{"style":272},[362],{"type":51,"value":363},"\"PROJ-42\"",{"type":38,"tag":181,"props":365,"children":366},{"style":228},[367],{"type":51,"value":256},{"type":38,"tag":181,"props":369,"children":371},{"class":183,"line":370},7,[372,377],{"type":38,"tag":181,"props":373,"children":374},{"style":238},[375],{"type":51,"value":376},"    \"fields\"",{"type":38,"tag":181,"props":378,"children":379},{"style":228},[380],{"type":51,"value":345},{"type":38,"tag":181,"props":382,"children":384},{"class":183,"line":383},8,[385,390,394,399],{"type":38,"tag":181,"props":386,"children":387},{"style":238},[388],{"type":51,"value":389},"      \"summary\"",{"type":38,"tag":181,"props":391,"children":392},{"style":228},[393],{"type":51,"value":246},{"type":38,"tag":181,"props":395,"children":396},{"style":272},[397],{"type":51,"value":398},"\"Checkout button unresponsive on mobile\"",{"type":38,"tag":181,"props":400,"children":401},{"style":228},[402],{"type":51,"value":256},{"type":38,"tag":181,"props":404,"children":406},{"class":183,"line":405},9,[407,412,416,421,425,430],{"type":38,"tag":181,"props":408,"children":409},{"style":238},[410],{"type":51,"value":411},"      \"status\"",{"type":38,"tag":181,"props":413,"children":414},{"style":228},[415],{"type":51,"value":293},{"type":38,"tag":181,"props":417,"children":418},{"style":238},[419],{"type":51,"value":420},"\"name\"",{"type":38,"tag":181,"props":422,"children":423},{"style":228},[424],{"type":51,"value":246},{"type":38,"tag":181,"props":426,"children":427},{"style":272},[428],{"type":51,"value":429},"\"In Progress\"",{"type":38,"tag":181,"props":431,"children":432},{"style":228},[433],{"type":51,"value":331},{"type":38,"tag":181,"props":435,"children":437},{"class":183,"line":436},10,[438,443,447,451,455,460],{"type":38,"tag":181,"props":439,"children":440},{"style":238},[441],{"type":51,"value":442},"      \"priority\"",{"type":38,"tag":181,"props":444,"children":445},{"style":228},[446],{"type":51,"value":293},{"type":38,"tag":181,"props":448,"children":449},{"style":238},[450],{"type":51,"value":420},{"type":38,"tag":181,"props":452,"children":453},{"style":228},[454],{"type":51,"value":246},{"type":38,"tag":181,"props":456,"children":457},{"style":272},[458],{"type":51,"value":459},"\"High\"",{"type":38,"tag":181,"props":461,"children":462},{"style":228},[463],{"type":51,"value":331},{"type":38,"tag":181,"props":465,"children":467},{"class":183,"line":466},11,[468,473,477,481,485,489],{"type":38,"tag":181,"props":469,"children":470},{"style":238},[471],{"type":51,"value":472},"      \"assignee\"",{"type":38,"tag":181,"props":474,"children":475},{"style":228},[476],{"type":51,"value":293},{"type":38,"tag":181,"props":478,"children":479},{"style":238},[480],{"type":51,"value":317},{"type":38,"tag":181,"props":482,"children":483},{"style":228},[484],{"type":51,"value":246},{"type":38,"tag":181,"props":486,"children":487},{"style":272},[488],{"type":51,"value":326},{"type":38,"tag":181,"props":490,"children":491},{"style":228},[492],{"type":51,"value":493}," }\n",{"type":38,"tag":181,"props":495,"children":497},{"class":183,"line":496},12,[498],{"type":38,"tag":181,"props":499,"children":500},{"style":228},[501],{"type":51,"value":502},"    }\n",{"type":38,"tag":181,"props":504,"children":506},{"class":183,"line":505},13,[507],{"type":38,"tag":181,"props":508,"children":509},{"style":228},[510],{"type":51,"value":511},"  },\n",{"type":38,"tag":181,"props":513,"children":515},{"class":183,"line":514},14,[516,521],{"type":38,"tag":181,"props":517,"children":518},{"style":238},[519],{"type":51,"value":520},"  \"changelog\"",{"type":38,"tag":181,"props":522,"children":523},{"style":228},[524],{"type":51,"value":345},{"type":38,"tag":181,"props":526,"children":528},{"class":183,"line":527},15,[529,534],{"type":38,"tag":181,"props":530,"children":531},{"style":238},[532],{"type":51,"value":533},"    \"items\"",{"type":38,"tag":181,"props":535,"children":536},{"style":228},[537],{"type":51,"value":538},": [\n",{"type":38,"tag":181,"props":540,"children":542},{"class":183,"line":541},16,[543,548,553,557,562,566,571,575,580,584,589,593,597],{"type":38,"tag":181,"props":544,"children":545},{"style":228},[546],{"type":51,"value":547},"      { ",{"type":38,"tag":181,"props":549,"children":550},{"style":238},[551],{"type":51,"value":552},"\"field\"",{"type":38,"tag":181,"props":554,"children":555},{"style":228},[556],{"type":51,"value":246},{"type":38,"tag":181,"props":558,"children":559},{"style":272},[560],{"type":51,"value":561},"\"status\"",{"type":38,"tag":181,"props":563,"children":564},{"style":228},[565],{"type":51,"value":312},{"type":38,"tag":181,"props":567,"children":568},{"style":238},[569],{"type":51,"value":570},"\"fromString\"",{"type":38,"tag":181,"props":572,"children":573},{"style":228},[574],{"type":51,"value":246},{"type":38,"tag":181,"props":576,"children":577},{"style":272},[578],{"type":51,"value":579},"\"To Do\"",{"type":38,"tag":181,"props":581,"children":582},{"style":228},[583],{"type":51,"value":312},{"type":38,"tag":181,"props":585,"children":586},{"style":238},[587],{"type":51,"value":588},"\"toString\"",{"type":38,"tag":181,"props":590,"children":591},{"style":228},[592],{"type":51,"value":246},{"type":38,"tag":181,"props":594,"children":595},{"style":272},[596],{"type":51,"value":429},{"type":38,"tag":181,"props":598,"children":599},{"style":228},[600],{"type":51,"value":493},{"type":38,"tag":181,"props":602,"children":604},{"class":183,"line":603},17,[605],{"type":38,"tag":181,"props":606,"children":607},{"style":228},[608],{"type":51,"value":609},"    ]\n",{"type":38,"tag":181,"props":611,"children":613},{"class":183,"line":612},18,[614],{"type":38,"tag":181,"props":615,"children":616},{"style":228},[617],{"type":51,"value":618},"  }\n",{"type":38,"tag":181,"props":620,"children":622},{"class":183,"line":621},19,[623],{"type":38,"tag":181,"props":624,"children":625},{"style":228},[626],{"type":51,"value":627},"}\n",{"type":38,"tag":39,"props":629,"children":630},{},[631],{"type":51,"value":632},"Things worth knowing:",{"type":38,"tag":634,"props":635,"children":636},"ul",{},[637,678,696,714],{"type":38,"tag":638,"props":639,"children":640},"li",{},[641,652,654,660,662,668,670,676],{"type":38,"tag":54,"props":642,"children":643},{},[644,650],{"type":38,"tag":67,"props":645,"children":647},{"className":646},[],[648],{"type":51,"value":649},"changelog",{"type":51,"value":651}," is where the diff lives.",{"type":51,"value":653}," For ",{"type":38,"tag":67,"props":655,"children":657},{"className":656},[],[658],{"type":51,"value":659},"jira:issue_updated",{"type":51,"value":661}," it lists each changed field with ",{"type":38,"tag":67,"props":663,"children":665},{"className":664},[],[666],{"type":51,"value":667},"fromString",{"type":51,"value":669},"/",{"type":38,"tag":67,"props":671,"children":673},{"className":672},[],[674],{"type":51,"value":675},"toString",{"type":51,"value":677},". If you only care about status transitions, read the changelog instead of diffing the whole issue.",{"type":38,"tag":638,"props":679,"children":680},{},[681,686,688,694],{"type":38,"tag":54,"props":682,"children":683},{},[684],{"type":51,"value":685},"Comment events",{"type":51,"value":687}," carry a ",{"type":38,"tag":67,"props":689,"children":691},{"className":690},[],[692],{"type":51,"value":693},"comment",{"type":51,"value":695}," object alongside the issue.",{"type":38,"tag":638,"props":697,"children":698},{},[699,704,706,712],{"type":38,"tag":54,"props":700,"children":701},{},[702],{"type":51,"value":703},"Deliveries include tracing headers",{"type":51,"value":705}," — ",{"type":38,"tag":67,"props":707,"children":709},{"className":708},[],[710],{"type":51,"value":711},"X-Atlassian-Webhook-Identifier",{"type":51,"value":713}," uniquely identifies the delivery attempt, which is handy for idempotency and log correlation.",{"type":38,"tag":638,"props":715,"children":716},{},[717],{"type":51,"value":718},"Payloads can be large (full issue with all custom fields). Budget for tens of kilobytes.",{"type":38,"tag":39,"props":720,"children":721},{},[722,724,730,732,737,739,745],{"type":51,"value":723},"Want to see the real thing without writing a handler? Open a free ",{"type":38,"tag":76,"props":725,"children":727},{"href":726},"/webhook-bin",[728],{"type":51,"value":729},"Webhook Bin",{"type":51,"value":731},", point a test webhook at it and trigger an event — or use the bin's sample catalog, which includes real-shaped ",{"type":38,"tag":67,"props":733,"children":735},{"className":734},[],[736],{"type":51,"value":659},{"type":51,"value":738}," and ",{"type":38,"tag":67,"props":740,"children":742},{"className":741},[],[743],{"type":51,"value":744},"jira:issue_created",{"type":51,"value":746}," events you can send to any endpoint with one click.",{"type":38,"tag":85,"props":748,"children":750},{"id":749},"securing-jira-webhooks",[751],{"type":51,"value":752},"Securing Jira webhooks",{"type":38,"tag":39,"props":754,"children":755},{},[756],{"type":51,"value":757},"How you secure a Jira webhook depends on how it was created:",{"type":38,"tag":634,"props":759,"children":760},{},[761,806,833],{"type":38,"tag":638,"props":762,"children":763},{},[764,769,771,777,779,788,790,796,798,804],{"type":38,"tag":54,"props":765,"children":766},{},[767],{"type":51,"value":768},"Dynamic webhooks (REST API) with a secret",{"type":51,"value":770}," are signed: Jira computes HMAC-SHA256 over the raw body and sends it as ",{"type":38,"tag":67,"props":772,"children":774},{"className":773},[],[775],{"type":51,"value":776},"sha256=…",{"type":51,"value":778}," in the ",{"type":38,"tag":54,"props":780,"children":781},{},[782],{"type":38,"tag":67,"props":783,"children":785},{"className":784},[],[786],{"type":51,"value":787},"X-Hub-Signature",{"type":51,"value":789}," header. Recompute it with your secret and compare in constant time. You can sanity-check an implementation with the free ",{"type":38,"tag":76,"props":791,"children":793},{"href":792},"/hmac-verification",[794],{"type":51,"value":795},"HMAC signature verifier",{"type":51,"value":797},", and the general pitfalls (raw body, timing-safe compare) are covered in ",{"type":38,"tag":76,"props":799,"children":801},{"href":800},"/blog/verify-webhook-signature",[802],{"type":51,"value":803},"Verify a webhook signature",{"type":51,"value":805},".",{"type":38,"tag":638,"props":807,"children":808},{},[809,814,816,822,824,832],{"type":38,"tag":54,"props":810,"children":811},{},[812],{"type":51,"value":813},"Classic webhooks (admin UI) are not signed.",{"type":51,"value":815}," Mitigate with a secret token in the URL path or query string (",{"type":38,"tag":67,"props":817,"children":819},{"className":818},[],[820],{"type":51,"value":821},"/hooks/jira?token=…",{"type":51,"value":823},") that your handler checks, and/or restrict inbound traffic to ",{"type":38,"tag":76,"props":825,"children":829},{"href":826,"rel":827},"https://support.atlassian.com/organization-administration/docs/ip-addresses-and-domains-for-atlassian-cloud-products/",[828],"nofollow",[830],{"type":51,"value":831},"Atlassian's published IP ranges",{"type":51,"value":805},{"type":38,"tag":638,"props":834,"children":835},{},[836,841],{"type":38,"tag":54,"props":837,"children":838},{},[839],{"type":51,"value":840},"Automation \"Send web request\"",{"type":51,"value":842}," lets you set your own auth header — treat it like any API client.",{"type":38,"tag":85,"props":844,"children":846},{"id":845},"delivery-behavior-and-reliability",[847],{"type":51,"value":848},"Delivery behavior and reliability",{"type":38,"tag":39,"props":850,"children":851},{},[852,854,859],{"type":51,"value":853},"Jira Cloud expects your endpoint to answer quickly with a 2xx. Slow or failing endpoints get their deliveries dropped — Jira's retry behavior is limited, so ",{"type":38,"tag":54,"props":855,"children":856},{},[857],{"type":51,"value":858},"do not treat webhook delivery as guaranteed",{"type":51,"value":860},". The standard hardening pattern:",{"type":38,"tag":862,"props":863,"children":864},"ol",{},[865,878,890],{"type":38,"tag":638,"props":866,"children":867},{},[868,870,876],{"type":51,"value":869},"Return ",{"type":38,"tag":67,"props":871,"children":873},{"className":872},[],[874],{"type":51,"value":875},"200",{"type":51,"value":877}," immediately, queue the event, process asynchronously.",{"type":38,"tag":638,"props":879,"children":880},{},[881,883,888],{"type":51,"value":882},"Deduplicate on ",{"type":38,"tag":67,"props":884,"children":886},{"className":885},[],[887],{"type":51,"value":711},{"type":51,"value":889}," (retried attempts reuse context).",{"type":38,"tag":638,"props":891,"children":892},{},[893],{"type":51,"value":894},"Reconcile periodically against the REST API for anything missed.",{"type":38,"tag":39,"props":896,"children":897},{},[898,900,906],{"type":51,"value":899},"If you need stronger guarantees than Jira gives you, put a stable relay endpoint in front of your handler: Webhook Relay stores every delivery and ",{"type":38,"tag":76,"props":901,"children":903},{"href":902},"/features/durable-retries",[904],{"type":51,"value":905},"retries towards your destination for up to 30 days",{"type":51,"value":907},", so a redeploy or an outage on your side no longer loses events.",{"type":38,"tag":85,"props":909,"children":911},{"id":910},"testing-your-integration",[912],{"type":51,"value":913},"Testing your integration",{"type":38,"tag":39,"props":915,"children":916},{},[917],{"type":51,"value":918},"The fast loop:",{"type":38,"tag":862,"props":920,"children":921},{},[922,938,963],{"type":38,"tag":638,"props":923,"children":924},{},[925,930,932,936],{"type":38,"tag":54,"props":926,"children":927},{},[928],{"type":51,"value":929},"Inspect first",{"type":51,"value":931}," — point the webhook at a ",{"type":38,"tag":76,"props":933,"children":934},{"href":726},[935],{"type":51,"value":729},{"type":51,"value":937}," and trigger real events to see exact headers and bodies.",{"type":38,"tag":638,"props":939,"children":940},{},[941,946,948,954,956,961],{"type":38,"tag":54,"props":942,"children":943},{},[944],{"type":51,"value":945},"Develop locally",{"type":51,"value":947}," — forward events to your machine with ",{"type":38,"tag":67,"props":949,"children":951},{"className":950},[],[952],{"type":51,"value":953},"relay forward --bucket jira http://localhost:8080/webhook",{"type":51,"value":955},"; the ",{"type":38,"tag":76,"props":957,"children":958},{"href":78},[959],{"type":51,"value":960},"local testing guide",{"type":51,"value":962}," walks through it.",{"type":38,"tag":638,"props":964,"children":965},{},[966,971],{"type":38,"tag":54,"props":967,"children":968},{},[969],{"type":51,"value":970},"Replay",{"type":51,"value":972}," captured deliveries against your handler while you iterate, instead of re-triggering issues in Jira.",{"type":38,"tag":85,"props":974,"children":976},{"id":975},"related-reading",[977],{"type":51,"value":978},"Related reading",{"type":38,"tag":634,"props":980,"children":981},{},[982,991,1010,1021],{"type":38,"tag":638,"props":983,"children":984},{},[985,989],{"type":38,"tag":76,"props":986,"children":987},{"href":78},[988],{"type":51,"value":81},{"type":51,"value":990}," — the localhost-focused walkthrough",{"type":38,"tag":638,"props":992,"children":993},{},[994,1008],{"type":38,"tag":76,"props":995,"children":997},{"href":996},"/blog/webhook-to-jira",[998,1000,1006],{"type":51,"value":999},"Send webhooks ",{"type":38,"tag":1001,"props":1002,"children":1003},"em",{},[1004],{"type":51,"value":1005},"to",{"type":51,"value":1007}," Jira",{"type":51,"value":1009}," — the reverse direction: creating issues from incoming webhooks",{"type":38,"tag":638,"props":1011,"children":1012},{},[1013,1019],{"type":38,"tag":76,"props":1014,"children":1016},{"href":1015},"/blog/confluence-webhooks",[1017],{"type":51,"value":1018},"Confluence webhooks",{"type":51,"value":1020}," — the same patterns on Jira's sibling",{"type":38,"tag":638,"props":1022,"children":1023},{},[1024,1030,1031],{"type":38,"tag":76,"props":1025,"children":1027},{"href":1026},"/blog/how-to-test-webhooks",[1028],{"type":51,"value":1029},"How to test webhooks",{"type":51,"value":738},{"type":38,"tag":76,"props":1032,"children":1034},{"href":1033},"/blog/what-is-webhook",[1035],{"type":51,"value":1036},"What is a webhook",{"type":38,"tag":1038,"props":1039,"children":1040},"style",{},[1041],{"type":51,"value":1042},"html .default .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}html .shiki span {color: var(--shiki-default);background: var(--shiki-default-bg);font-style: var(--shiki-default-font-style);font-weight: var(--shiki-default-font-weight);text-decoration: var(--shiki-default-text-decoration);}",{"title":7,"searchDepth":259,"depth":259,"links":1044},[1045,1046,1047,1048,1049,1050,1051],{"id":87,"depth":234,"text":90},{"id":162,"depth":234,"text":165},{"id":197,"depth":234,"text":200},{"id":749,"depth":234,"text":752},{"id":845,"depth":234,"text":848},{"id":910,"depth":234,"text":913},{"id":975,"depth":234,"text":978},"markdown","content:blog:jira-webhooks-guide.md","content","blog/jira-webhooks-guide.md","blog/jira-webhooks-guide","md",{"loc":4},1783373260845]