Receive Jira Issue Transition Webhook
POST/api/support/webhooks/jira
The inbound endpoint Jira calls when an issue changes status. Point a Jira issue updated webhook at this URL (with the shared secret in the token query parameter or the X-Webhook-Token header). When the issue has moved to a release status, every support ticket linked to that issue key is updated: it gets a release link (build + deploy URL), an internal note announcing the release, moves to awaiting_release if it is still unresolved and not already there, and any AI draft that was waiting for a deploy is released to the agents. Nothing is sent to the customer by this endpoint — an agent still replies and resolves. The changes are made as the desk's automation user (an active support admin, otherwise any active agent).
This endpoint currently requires session authentication; Personal Access Token scope support is in progress.
Authentication: none — no bearer token, no session, no tenant. The request must carry the shared secret configured for this integration on the SKU.io side, either as ?token=<secret> or as an X-Webhook-Token: <secret> header (the query parameter wins when both are present). A missing or wrong secret — or no secret configured on the server — is refused with 403 before the body is read.
Query parameters
token(string, required unless theX-Webhook-Tokenheader is sent) — the shared secret
Request body — Jira's standard issue webhook payload. Only these fields are read; everything else is ignored:
issue.key(string, required) — the issue key, e.g.ENG-4521. Must match<PROJECT>-<number>(case-insensitive; upper-cased before matching). Without a valid key nothing is donechangelog.items[]— the item whosefieldisstatussupplies the new status from itstoString; this takes precedence overissue.fields.status.nameissue.fields.status.name(string) — the issue's current status, used when the changelog carries no status itemissue.fields.fixVersions[0].name(string, optional) — recorded as the build identifier;masterwhen absentuser.displayName(string, optional) — named in the internal note ("Jira ENG-4521 moved to Released by Priya Natarajan.")- deploy URL (optional, must be an absolute
https://URL) — read from the first of: a top-leveldeploy_url, the Jira custom field configured for it, orissue.fields.deploy_url
Release statuses: Released to Master, Released, Done (compared case-insensitively). Any other status is acknowledged with 200 and handled: false.
Response fields (data)
handled(boolean) — true when the transition was a release and linked tickets were processed (possibly zero of them)reason(string, nullable) — why nothing was done:no issue key,not a release status, orno active support agent to act as; null when handledissue_key(string, nullable) — the upper-cased key that was readstatus(string, nullable) — the status that was readtickets[](array of integers) — ids of the support tickets that were updated
There is no request validation: an unparseable or empty body is answered with 200 and reason: "no issue key". Retrying the same transition is safe — the release link is upserted and a ticket already awaiting release is not moved again.
Request
Responses
- 200
- 401
- 403
- 422
- 429
OK
Response Headers
Unauthenticated — the bearer token is missing, revoked, expired, or malformed. Never retry automatically; fix the credential. See the Errors guide.
Forbidden
Response Headers
Validation failed — the body is a field → messages map (Laravel shape) or the platform envelope with a stable machine-readable code. Fix the payload and resubmit.
Rate limited — platform limit is 1,000 requests/min; individual tokens may carry lower limits. Honor the Retry-After header before retrying. See the Rate Limits guide.