This workflow corresponds to n8n.io template #17115 — we link there as the canonical source.
The workflow JSON
Copy or download the full n8n JSON below. Paste it into a new n8n workflow, add your credentials, activate. Full import guide →
{
"name": "Draft incident postmortems with PagerDuty, Confluence and Slack",
"tags": [
{
"name": "creator-template"
},
{
"name": "incident"
},
{
"name": "pagerduty"
},
{
"name": "confluence"
},
{
"name": "slack"
}
],
"nodes": [
{
"id": "b56486a7-7f61-4693-8b4a-667df5845b59",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-208,
672
],
"parameters": {
"width": 480,
"height": 896,
"content": "## Draft incident postmortems with PagerDuty, Confluence and Slack\n\n### How it works\n\nThis workflow drafts incident postmortems from PagerDuty incident data. It can be started manually for testing or by a PagerDuty resolved-incident webhook. It normalizes the incident payload, retrieves incident details and timeline events, builds a review-ready postmortem draft, creates a Confluence page, notifies the incident owner in Slack, and logs the result to Google Sheets.\n\n### Setup steps\n\n- [ ] Configure the PagerDuty resolved-incident webhook to call the n8n webhook URL.\n- [ ] Add PagerDuty API credentials to the incident details and timeline request nodes.\n- [ ] Update `pagerduty_base_url`, `confluence_base_url`, `confluence_space_key`, and `confluence_parent_page_id` in `Set Config Variables`.\n- [ ] Add Confluence credentials with permission to create pages in the selected space.\n- [ ] Add Slack OAuth credentials with permission to post messages to the review channel.\n- [ ] Optional: add Google Sheets OAuth credentials and set the spreadsheet ID for the postmortem log.\n\n### Customization\n\nAdjust the postmortem structure in `Generate Postmortem Draft`, change the Confluence destination variables, and customize the Slack message or Google Sheets fields to match your incident review process. Keep human review before publishing incident reports."
},
"typeVersion": 1
},
{
"id": "f8ce931e-dbb1-4365-b344-323609f9f36f",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
352,
672
],
"parameters": {
"color": 7,
"width": 240,
"height": 560,
"content": "## Start incident workflow\n\nContains the manual and PagerDuty webhook entry points that start the postmortem drafting process when run manually or when an incident is resolved."
},
"typeVersion": 1
},
{
"id": "92e2d1b7-5005-4c16-9b35-3320a865deae",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1056,
672
],
"parameters": {
"color": 7,
"width": 240,
"height": 448,
"content": "## Set workflow configuration\n\nDefines reusable configuration values such as PagerDuty and Confluence base URLs, the Confluence space key, parent page ID, Slack channel, and optional logging settings."
},
"typeVersion": 1
},
{
"id": "ce8252a1-7b7a-44d5-990c-2c06c38786ee",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1616,
704
],
"parameters": {
"color": 7,
"width": 528,
"height": 512,
"content": "## Load PagerDuty incident data\n\nNormalizes the incoming PagerDuty incident payload, then fetches the full incident details and timeline events from PagerDuty in parallel."
},
"typeVersion": 1
},
{
"id": "66a27454-9b70-4af4-9999-92dd6a81f188",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
2544,
720
],
"parameters": {
"color": 7,
"width": 240,
"height": 400,
"content": "## Build postmortem content\n\nConverts the normalized incident context into a structured postmortem draft prepared for human review in Confluence."
},
"typeVersion": 1
},
{
"id": "9726ed85-58e6-43ec-8b68-4828ce09376e",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
3152,
704
],
"parameters": {
"color": 7,
"width": 576,
"height": 560,
"content": "## Publish and notify teams\n\nCreates the Confluence postmortem draft, notifies the incident owner in Slack, and appends a tracking row to Google Sheets."
},
"typeVersion": 1
},
{
"id": "a59fabdb-4e63-4e7b-96e2-6d99f6c650db",
"name": "Manual Start",
"type": "n8n-nodes-base.manualTrigger",
"position": [
400,
900
],
"parameters": {},
"typeVersion": 1
},
{
"id": "f95dcc28-67ae-4a20-85c5-e7f6a1ebda1d",
"name": "When PagerDuty Incident Resolved",
"type": "n8n-nodes-base.webhook",
"position": [
400,
1080
],
"parameters": {
"path": "pagerduty/incident-resolved",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "f90a5f74-656f-4ace-8e9f-cf6aa2f4610e",
"name": "Set Config Variables",
"type": "n8n-nodes-base.set",
"position": [
1104,
960
],
"parameters": {
"options": {},
"assignments": {
"assignments": [
{
"id": "59477e0d-551b-4071-8e02-3f5b16845b8e",
"name": "pagerduty_base_url",
"type": "string",
"value": "https://api.pagerduty.com"
},
{
"id": "4b3ec453-bbf3-4780-85ea-4aa53600fabc",
"name": "confluence_base_url",
"type": "string",
"value": "https://your-domain.atlassian.net/wiki"
},
{
"id": "302434c8-2b59-42d9-b55f-cae9c878eca3",
"name": "confluence_space_key",
"type": "string",
"value": "ENG"
},
{
"id": "a6efdcc0-ab9e-4daa-a1eb-e31e9e8a55cc",
"name": "confluence_parent_page_id",
"type": "string",
"value": "123456789"
},
{
"id": "7ee1f4c8-5fd2-4cbf-8c0d-f41532c33f11",
"name": "slack_channel_id",
"type": "string",
"value": "C0123456789"
},
{
"id": "fd22a223-e239-4eb5-8051-6e5d25c92cae",
"name": "postmortem_owner",
"type": "string",
"value": "user@example.com"
},
{
"id": "e34a8569-034b-4d19-9828-ec180b066fa1",
"name": "google_sheets_spreadsheet_id",
"type": "string",
"value": "your-postmortem-log-sheet-id"
},
{
"id": "5d3f5208-f1c3-4353-994e-9423f8201285",
"name": "minimum_severity_for_postmortem",
"type": "string",
"value": "P2"
},
{
"id": "5e420b8f-5556-439d-9d6c-674027b3da05",
"name": "include_action_items",
"type": "boolean",
"value": "true"
},
{
"id": "8e0060bd-c8c9-4f8e-8fa8-65f13dea63a6",
"name": "publish_as_draft",
"type": "boolean",
"value": "true"
}
]
},
"includeOtherFields": true
},
"typeVersion": 3.4
},
{
"id": "20c3a528-0310-450c-b3cd-10165e9a4bdd",
"name": "Normalize Incident Data",
"type": "n8n-nodes-base.code",
"position": [
1664,
960
],
"parameters": {
"jsCode": "const item = $input.first().json;\nconst cfg = {\n pagerduty_base_url: item.pagerduty_base_url,\n confluence_base_url: item.confluence_base_url,\n confluence_space_key: item.confluence_space_key,\n confluence_parent_page_id: item.confluence_parent_page_id,\n slack_channel_id: item.slack_channel_id,\n postmortem_owner: item.postmortem_owner,\n google_sheets_spreadsheet_id: item.google_sheets_spreadsheet_id,\n minimum_severity_for_postmortem: item.minimum_severity_for_postmortem,\n include_action_items: item.include_action_items === true || item.include_action_items === 'true',\n publish_as_draft: item.publish_as_draft === true || item.publish_as_draft === 'true',\n};\n\nconst payload = item.body || item.event || item;\nconst incident = payload.incident || payload.data || payload;\nconst now = new Date();\n\nreturn [{\n json: {\n config: cfg,\n incidentId: incident.id || 'PABC123',\n incidentNumber: incident.incident_number || incident.number || '1001',\n incidentTitle: incident.title || incident.summary || 'Checkout API latency increase',\n serviceName: incident.service?.summary || incident.service_name || 'Checkout API',\n status: incident.status || 'resolved',\n urgency: incident.urgency || 'high',\n severity: incident.severity || 'P2',\n htmlUrl: incident.html_url || 'https://pagerduty.example/incidents/PABC123',\n createdAt: incident.created_at || new Date(now.getTime() - 90*60*1000).toISOString(),\n resolvedAt: incident.resolved_at || now.toISOString(),\n owner: incident.assignments?.[0]?.assignee?.summary || cfg.postmortem_owner,\n }\n}];"
},
"typeVersion": 2
},
{
"id": "bda98892-7e52-4bb1-a90c-c4ec3f6d0745",
"name": "Get Incident Details",
"type": "n8n-nodes-base.httpRequest",
"notes": "Select PagerDuty credentials in this node. Do not paste API tokens into headers.",
"position": [
2000,
860
],
"parameters": {
"url": "={{ $json.config.pagerduty_base_url + \"/incidents/\" + $json.incidentId }}",
"options": {}
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "f3f2cc6c-6b5e-4bf6-80f1-68c365df2a31",
"name": "Get Timeline Events",
"type": "n8n-nodes-base.httpRequest",
"notes": "Select PagerDuty credentials in this node. Use pagination if your incidents have long timelines.",
"position": [
2000,
1060
],
"parameters": {
"url": "={{ $json.config.pagerduty_base_url + \"/incidents/\" + $json.incidentId + \"/log_entries?include[]=channels\" }}",
"options": {}
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "864487c0-675b-4771-a13f-f1642c150290",
"name": "Generate Postmortem Draft",
"type": "n8n-nodes-base.code",
"position": [
2592,
960
],
"parameters": {
"jsCode": "const source = $input.first().json;\n const cfg = source.config || {};\n const start = new Date(source.createdAt || Date.now());\n const end = new Date(source.resolvedAt || Date.now());\n const minutes = Math.max(0, Math.round((end - start) / 60000));\n\n const timeline = [\n `- ${start.toISOString()} Incident opened for ${source.serviceName}`,\n `- ${new Date(start.getTime() + 15*60000).toISOString()} Initial triage started by ${source.owner}`,\n `- ${new Date(start.getTime() + 45*60000).toISOString()} Mitigation applied or rollback started`,\n `- ${end.toISOString()} Incident resolved`\n ];\n\n const title = `Postmortem: ${source.incidentTitle} (${source.incidentNumber})`;\n const storage = `\n<h2>Summary</h2>\n<p>${source.incidentTitle}</p>\n<h2>Impact</h2>\n<p>Document customer impact, affected regions, and affected product areas here.</p>\n<h2>Incident details</h2>\n<ul>\n <li>PagerDuty incident: ${source.htmlUrl}</li>\n <li>Service: ${source.serviceName}</li>\n <li>Severity: ${source.severity}</li>\n <li>Duration: ${minutes} minutes</li>\n <li>Owner: ${source.owner}</li>\n</ul>\n<h2>Timeline</h2>\n<pre>${timeline.join('\\n')}</pre>\n<h2>Root cause</h2>\n<p>Needs review. Add the confirmed root cause after engineering review.</p>\n<h2>What went well</h2>\n<ul><li>Needs review.</li></ul>\n<h2>What can improve</h2>\n<ul><li>Needs review.</li></ul>\n<h2>Action items</h2>\n<ul>\n <li>[ ] Add owner, due date, and ticket link for each remediation item.</li>\n</ul>`.trim();\n\n return [{\n json: {\n ...source,\n postmortemTitle: title,\n confluenceStorageBody: storage,\n durationMinutes: minutes,\n createdForReview: true\n }\n }];"
},
"typeVersion": 2
},
{
"id": "912bcdcd-69e3-45e3-aa88-5970a58c7fef",
"name": "Post Draft to Confluence",
"type": "n8n-nodes-base.httpRequest",
"notes": "Select Confluence credentials. Keep pages reviewable before sharing them broadly.",
"position": [
3200,
860
],
"parameters": {
"url": "={{ $json.config.confluence_base_url + \"/rest/api/content\" }}",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"type\": \"page\",\n \"title\": $json.postmortemTitle,\n \"ancestors\": [{ \"id\": $json.config.confluence_parent_page_id }],\n \"space\": { \"key\": $json.config.confluence_space_key },\n \"body\": {\n \"storage\": {\n \"value\": $json.confluenceStorageBody,\n \"representation\": \"storage\"\n }\n },\n \"metadata\": {\n \"properties\": {\n \"status\": { \"value\": \"Needs review\" }\n }\n }\n}\n}}",
"sendBody": true,
"contentType": "json",
"specifyBody": "json"
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "024e56bb-0e3b-46b8-98e6-46a7e660046e",
"name": "Send Slack Notification",
"type": "n8n-nodes-base.httpRequest",
"notes": "Select Slack OAuth credentials. Do not use a hardcoded bot token.",
"position": [
3584,
860
],
"parameters": {
"url": "https://slack.com/api/chat.postMessage",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"channel\": $json.config.slack_channel_id,\n \"text\": \"Postmortem draft created for \" + $json.incidentTitle,\n \"blocks\": [\n { \"type\": \"section\", \"text\": { \"type\": \"mrkdwn\", \"text\": \"*Postmortem draft created*\\nIncident: \" + $json.incidentTitle + \"\\nService: \" + $json.serviceName + \"\\nOwner: \" + $json.owner } }\n ]\n}\n}}",
"sendBody": true,
"contentType": "json",
"specifyBody": "json"
},
"notesInFlow": true,
"typeVersion": 4.2
},
{
"id": "12428c21-dec9-4c82-9c27-257de43b6b60",
"name": "Update Postmortem Log",
"type": "n8n-nodes-base.httpRequest",
"notes": "Optional. Select Google Sheets OAuth credentials or disable this node if you do not need a postmortem log.",
"position": [
3584,
1100
],
"parameters": {
"url": "={{ \"https://sheets.googleapis.com/v4/spreadsheets/\" + $json.config.google_sheets_spreadsheet_id + \"/values/Postmortems!A:G:append?valueInputOption=USER_ENTERED\" }}",
"method": "POST",
"options": {},
"jsonBody": "={{\n{\n \"values\": [[\n $json.incidentId,\n $json.incidentTitle,\n $json.serviceName,\n $json.severity,\n $json.durationMinutes,\n $json.owner,\n new Date().toISOString()\n ]]\n}\n}}",
"sendBody": true,
"contentType": "json",
"specifyBody": "json"
},
"notesInFlow": true,
"typeVersion": 4.2
}
],
"active": false,
"settings": {
"binaryMode": "separate",
"executionOrder": "v1"
},
"nodeGroups": [],
"connections": {
"Manual Start": {
"main": [
[
{
"node": "Set Config Variables",
"type": "main",
"index": 0
}
]
]
},
"Get Timeline Events": {
"main": [
[
{
"node": "Generate Postmortem Draft",
"type": "main",
"index": 0
}
]
]
},
"Get Incident Details": {
"main": [
[
{
"node": "Generate Postmortem Draft",
"type": "main",
"index": 0
}
]
]
},
"Set Config Variables": {
"main": [
[
{
"node": "Normalize Incident Data",
"type": "main",
"index": 0
}
]
]
},
"Normalize Incident Data": {
"main": [
[
{
"node": "Get Incident Details",
"type": "main",
"index": 0
},
{
"node": "Get Timeline Events",
"type": "main",
"index": 0
}
]
]
},
"Post Draft to Confluence": {
"main": [
[
{
"node": "Send Slack Notification",
"type": "main",
"index": 0
},
{
"node": "Update Postmortem Log",
"type": "main",
"index": 0
}
]
]
},
"Generate Postmortem Draft": {
"main": [
[
{
"node": "Post Draft to Confluence",
"type": "main",
"index": 0
}
]
]
},
"When PagerDuty Incident Resolved": {
"main": [
[
{
"node": "Set Config Variables",
"type": "main",
"index": 0
}
]
]
}
}
}
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow creates a Confluence postmortem draft for resolved PagerDuty incidents, then notifies the incident owner in Slack and optionally logs the draft in Google Sheets. Triggers manually for testing or receives a PagerDuty webhook when an incident is resolved. Loads…
Source: https://n8n.io/workflows/17115/ — original creator credit. Request a take-down →
Related workflows
Workflows that share integrations, category, or trigger type with this one. All free to copy and import.
Worflow. Uses whatsAppTrigger, httpRequest, whatsApp. Event-driven trigger; 94 nodes.
Webhook Slack. Uses theHiveProjectTrigger, stickyNote, httpRequest, theHiveProject. Event-driven trigger; 63 nodes.
Key Features: Direct Case Management: Modify case details such as assignee, severity, status, and more through intuitive form inputs embedded within Slack messages. Seamless Integration: Assumes match
N8N Complete Final. Uses telegramTrigger, dataTable, telegram, mqtt. Event-driven trigger; 58 nodes.
Pede Ai. Uses httpRequest, telegram, postgres, telegramTrigger. Event-driven trigger; 57 nodes.