Jira Service Management via n8n
This guide connects a WhatsApp line in Spun to Jira Service Management with a ready-made n8n workflow. Every WhatsApp conversation becomes one request in your service project, follow-up messages are added to it as comments, and public agent comments in Jira go back to the customer on WhatsApp.
It builds on Connect a Helpdesk to WhatsApp, which explains the events, signatures and loop guards the workflow relies on. Read that guide first if you plan to change the workflow.
What it does
| Direction | What happens |
|---|---|
| WhatsApp to Jira | The first message of a conversation creates a request of the request type you choose. The customer's WhatsApp number is stored in a "WhatsApp number" field on the request, and their name and number appear in the summary and description. |
| WhatsApp to Jira | Later messages are added to the open request as public comments, prefixed with the customer's name and number. Media arrives as a link that stays valid for 24 hours. |
| WhatsApp to Jira | A message after the request is resolved reopens it when you set a reopen transition. Without one, the message starts a new request. |
| Spun to Jira | Replies your team sends from the Spun inbox are added to the request as internal comments, so the agent in Jira sees the whole exchange. |
| Spun to Jira | Archiving the conversation in Spun runs your resolve transition. Unarchiving it runs the reopen transition, if you set one. |
| Jira to WhatsApp | A public comment by an agent is sent to the customer on WhatsApp. Internal comments, comments by customers, apps and automation, and the workflow's own comments are never sent. |
Group chats are not supported and are skipped: a group has no phone number, so the workflow cannot link it to a request.
Who the request is from. The workflow does not create Jira customers. A dedicated integration account raises every WhatsApp request and writes every comment the workflow adds, because Jira only lets an API caller comment as itself. The WhatsApp name and number in each comment show who actually wrote it.
Prerequisites
- A Jira Service Management site (
your-site.atlassian.net) with a service project for WhatsApp requests. - A project admin who can add a field to a request type and look up workflow transitions, and a Jira admin once, to create the webhook.
- An Atlassian account for the integration, such as "Spun WhatsApp", that is an agent on the service project. Whether the agent seat is billed depends on your Jira plan.
- An n8n instance that your Jira site and Spun can reach over HTTPS with a publicly trusted certificate, either n8n Cloud or a self-hosted install. The workflow uses only the nodes that ship with n8n.
- A Spun workspace with a connected WhatsApp line and access to the Webhooks page in Settings.
Setup
The workflow file and a step-by-step setup document are in the Spun repository under integrations/helpdesk/jira-service-management/. The setup document lists every value with where to find it. In outline:
- Create an API token for the integration account. Signed in as that account, create a classic API token in your Atlassian account security settings. In n8n, create a Basic Auth credential with the account's email as the user and the token as the password. The token stays in your n8n; Spun never asks for it or stores it.
- Add a "WhatsApp number" field. Create a short text field, add it to the request type WhatsApp conversations should use, and note its field id (
customfield_followed by a number). The setup document shows how to check that the request type accepts it. - Look up your transitions. Note the id of the transition that resolves a request and, optionally, one that reopens a resolved request. If the resolve screen requires a resolution, note its name too.
- Import the workflow into n8n and open the Settings node. Paste your site URL, the service desk id, the request type id, the project key, the field id, the transitions and the integration account's account id.
- Choose the reply URL. Replace the placeholder at the end of the Helpdesk reply node's path with a long random string, then activate the workflow.
- Create the Jira webhook. As a Jira admin, go to Jira settings, System, WebHooks, and create a webhook to the workflow's reply URL with the event Comment: created, a JQL filter of
project = YOUR-KEY, and a secret. Paste the secret into the Settings node. Never leave the JQL filter empty: an empty filter sends comments from every project on your site. - Create a Spun API key on the Webhooks page under Manage API Keys with the
send_messagescope. Tick "Close & Reopen Conversations" as well (themanage_conversationsscope) if you want a request resolved in Jira to archive the conversation in Spun. Store the key in an n8n Header Auth credential and select it on the three nodes that call Spun. - Subscribe Spun to the workflow. Copy the production URL of the workflow's Spun events node and create a webhook subscription on the Webhooks page for
message.inbound,message.outbound,conversation.closedandconversation.reopened, with the payload template set to raw. Paste the signing secret into the Settings node. - Send a test message to the line from another phone. The Delivery Log on the Webhooks page shows the event, the n8n execution list shows the run, and a new request appears in Jira. Add a public comment to it as an agent and the reply reaches the phone.
Rotate the webhook secret, the signing secret, the API token and the Spun API key whenever someone who had access to the n8n instance leaves. Atlassian API tokens expire on the date chosen when they are created, so replace the token in n8n before then.
Check your customer notifications
The integration account is the reporter of every WhatsApp request, so the customer notifications Jira sends for those requests go to that account's email address, not to the customer. Point the account at a mailbox that can receive them, or turn those notifications off for the WhatsApp request type under Project settings, Customer notifications.
Message mapping
| Spun | Jira Service Management |
|---|---|
First message.inbound of a conversation | New request of your request type. Summary "WhatsApp: " followed by the first line of the message text (the caption for media, or the media type such as [image] when there is no caption), cut at 80 characters. Description [WhatsApp] Name (+number): text, and the number in the WhatsApp number field. |
Later message.inbound | Public comment on the open request: [WhatsApp] Name (+number): text. |
| Message after the request was resolved | The request is reopened and gets the comment, when a reopen transition is set. Otherwise a new request. |
| Media message | The same comment with the file type and size and a link to the file, valid for 24 hours. The caption follows the link. |
| Media still processing | A comment saying the media is still being processed, with a pointer to the conversation in Spun. The link is not sent later. |
message.outbound sent from the Spun inbox | Internal comment: [Sent from Spun] Agent name: text. |
message.outbound that the workflow itself sent | Ignored. |
conversation.closed | Resolve transition. |
conversation.reopened | Reopen transition, if one is set. |
| Public agent comment in Jira | WhatsApp message to the customer, text only. |
| Internal comment, or a comment by a customer, an app, automation or the integration account | Not sent. |
| Group chat | Skipped. Groups are not supported: they carry no phone number, so no request can be linked to them. |
Limits
- Resolving a request in Jira archives the conversation in Spun only when you turn that on. The workflow ships with
close_in_spun_when_desk_closesset to false, so closing starts out one-way, from Spun to Jira. To enable the other direction, set it to true in the Settings node, give the API key themanage_conversationsscope and add the Issue: updated event to the Jira webhook; the workflow then callsPOST /api/integrations/conversations/closeand/reopen. Check the first close in the n8n execution list before relying on it. - Resolving can be refused. If the resolve transition is not available from the request's current status, or its screen requires a field the workflow does not send, archiving in Spun leaves the request open in Jira and the n8n execution shows the reason. A transition available from every status is the simplest choice.
- Busy conversations can hit Jira's per-request write limit. Jira accepts 20 writes to one request in 2 seconds and 100 in 30 seconds, and every comment the workflow adds is a write. The workflow retries a refused comment twice, a few seconds apart. When a customer sends a longer burst, the extra messages are not added to the request; the n8n execution fails with Jira's response and can be re-run. The messages stay in the Spun inbox.
- Media is sent as a link, not as a Jira attachment. The link works for 24 hours. A file that was still processing when the message arrived is reported as pending and is not sent afterwards.
- Replies from Jira are text only. Attachments an agent adds to a comment are not forwarded to WhatsApp. Jira text formatting arrives as it was typed: bold and italic look the same in WhatsApp, links with link text show both.
- Jira retries webhook deliveries. A delivery that n8n did not accept is retried up to five times over about an hour; the workflow sends each reply once. Replies that never arrived are listed by Jira's failed-webhooks endpoint, and the workflow does not poll for them.
- Each delivered event uses AI tokens from your Spun plan. When the budget is exhausted, deliveries are skipped and the Delivery Log shows the reason. Top up or raise the budget to resume. How this is metered for helpdesk use is still being reviewed.
- The workflow remembers requests in n8n's workflow data. If you reset the workflow or move it to another n8n instance, the next message for each conversation finds the open request by its WhatsApp number field and continues there. Agent replies on a request the workflow no longer remembers still reach the customer, using the number on the request, but resolving such a request in Jira does not archive the conversation in Spun until a new message has passed through.
- One open request per conversation. Splitting a long conversation into several requests by day is not supported. Comments longer than 32,000 characters are cut.
Troubleshooting
- The Delivery Log shows
401from n8n. The Spun signing secret in the Settings node does not match the subscription. Copy it again, or rotate it on the Webhooks page and paste the new value. - The Delivery Log shows a delivery but no request appears. Open the n8n execution. A Jira error body is kept in the item that failed; the most common causes are a request type that does not have the WhatsApp number field, another required field on the request type, an integration account that is not an agent on the project, or a service desk or request type id that does not exist.
- The n8n execution stops with "Set jira_phone_field_id" or "Set jira_project_key". A Settings value is still a placeholder. Fill it in as described in the setup document.
- A reply from Jira never reaches WhatsApp. Check that the webhook is enabled, that its JQL filter names your project, that the comment was public (Reply to customer) and written by an agent, and that the webhook secret in the Settings node is the one you set in Jira. The n8n execution shows the reason a reply was dropped, for example a signature that did not match.
- The customer receives their own message back on WhatsApp. The account id in the Settings node does not match the account the API token belongs to.
- The API token stops working. The token has expired or was revoked, or repeated failed sign-ins locked the account out of the API. Sign in once in the browser as the integration account, then create a new token if needed.
- Duplicate requests for one customer. The previous request was resolved and no reopen transition is set, so a new request is expected. If the first request is still open, check that its WhatsApp number field holds the number with the leading
+. - Deliveries show
Skipped: AI token budget exhausted. Top up on the Billing page or raise the budget. Catch up on missed messages withGET /api/integrations/messagesonce deliveries resume.
For the full list of events, headers, retry rules and loop guards, see Connect a Helpdesk to WhatsApp.