This workflow corresponds to n8n.io template #14709 — we link there as the canonical source.
This workflow follows the Gmail → Slack recipe pattern — see all workflows that pair these two integrations.
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 →
{
"id": "9RPNkviS0UijNC2y",
"meta": {
"templateCredsSetupCompleted": true
},
"name": "Smart Partner API Usage Monitoring with Slack, Jira & Gmail Alerts",
"tags": [],
"nodes": [
{
"id": "86db7aa7-594d-42ea-ae03-da29bb8a3e62",
"name": "Validate Partner Usage Payload",
"type": "n8n-nodes-base.code",
"position": [
176,
-208
],
"parameters": {
"jsCode": "const data = items[0].json.body;\nlet errors = [];\n\nif (!data.partner_id) errors.push(\"partner_id missing\");\nif (!data.partner_name) errors.push(\"partner_name missing\");\nif (data.quota === undefined || data.quota === null) errors.push(\"quota missing\");\nif (data.consumed === undefined || data.consumed === null) errors.push(\"consumed missing\");\n\n// Numeric validation\nif (data.quota !== undefined && isNaN(Number(data.quota))) {\n errors.push(\"quota not a number\");\n}\nif (data.consumed !== undefined && isNaN(Number(data.consumed))) {\n errors.push(\"consumed not a number\");\n}\n\n// If any validation failed \u2014 go to fallback\nif (errors.length > 0) {\n return [\n {\n json: {\n status: \"invalid\",\n errors,\n ...data\n }\n }\n ];\n}\n\n// If everything is valid\nreturn [\n {\n json: {\n status: \"valid\",\n ...data\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "7189fcd7-4085-4e68-86ba-fd4d6b7ffe18",
"name": "Is Usage Payload Valid?",
"type": "n8n-nodes-base.if",
"position": [
400,
-208
],
"parameters": {
"options": {},
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "7b67ced7-941e-48d5-9d8e-38e54a32894f",
"operator": {
"name": "filter.operator.equals",
"type": "string",
"operation": "equals"
},
"leftValue": "={{ $json.status }}",
"rightValue": "valid"
}
]
}
},
"typeVersion": 2.2
},
{
"id": "0c3c01f8-7798-4969-8731-405993a8c52c",
"name": "Calculate API Usage Percentage",
"type": "n8n-nodes-base.code",
"position": [
752,
-224
],
"parameters": {
"jsCode": "const item = items[0].json;\n\nconst quota = Number(item.quota);\nconst consumed = Number(item.consumed);\n\nif (!quota || isNaN(quota) || isNaN(consumed)) {\n // invalid numeric values \u2192 fallback\n return [\n {\n json: {\n action: \"invalid_usage\",\n ...item\n }\n }\n ];\n}\n\n// Calculate usage %\nconst usage_pct = Math.round((consumed / quota) * 100 * 100) / 100; // 2 decimals\n\n// If below 80% \u2192 stop workflow\nif (usage_pct < 80) {\n return [\n {\n json: {\n action: \"no_alert\",\n usage_pct,\n ...item\n }\n }\n ];\n}\n\n// If >= 80 \u2192 proceed to next step (dedupe check)\nreturn [\n {\n json: {\n action: \"proceed\",\n usage_pct,\n ...item\n }\n }\n];\n"
},
"typeVersion": 2
},
{
"id": "89ae6be3-08e6-483e-8463-6bf6923aef06",
"name": "Create Jira Partner Review Ticket",
"type": "n8n-nodes-base.jira",
"position": [
1440,
-208
],
"parameters": {
"project": {
"__rl": true,
"mode": "list",
"value": "10000",
"cachedResultName": "n8n sample project"
},
"summary": "=Partner {{$json[\"partner_name\"]}} reached {{Math.round($json[\"usage_pct\"])}}% usage \u2013 Review Plan Tier",
"issueType": {
"__rl": true,
"mode": "list",
"value": "10003",
"cachedResultName": "Task"
},
"additionalFields": {
"description": "=Partner Usage Alert \nPartner Name:{{$json[\"partner_name\"]}} \nPartner ID: {{$json[\"partner_id\"]}}\nPlan: {{$json[\"plan\"]}} \nQuota:{{$json[\"quota\"]}}\nConsumed: {{$json[\"consumed\"]}}\nUsage %: {{Math.round($json[\"usage_pct\"])}} \nTimestamp:{{$json[\"timestamp\"]}} \nRecommended Action: - Review current plan tier. - Contact partner for possible upgrade discussion."
}
},
"credentials": {
"jiraSoftwareCloudApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "28e5efce-a2ce-4b43-b5d9-bf7ac9c85d2f",
"name": "Send Slack Partner Usage Alert",
"type": "n8n-nodes-base.slack",
"position": [
1760,
-208
],
"parameters": {
"text": "=\ud83d\udea8 *Partner Usage Alert* \n*Partner:*{{ $('Validate Partner Usage Payload').item.json.partner_name }} \n*Usage:* {{Math.round($json[\"usage_pct\"])}}% \n*Plan:*{{ $('Validate Partner Usage Payload').item.json.plan }} \n*Timestamp:* {{ $('Validate Partner Usage Payload').item.json.timestamp }} \n*A Jira ticket has been created for review:* {{ $json.key }} \nRecommended Action: \n\u2022 Review the current plan tier\n\u2022 Consider reaching out for upgrade discussion.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C09S57E2JQ2",
"cachedResultName": "n8n"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "3e6fce0c-9368-4a9b-b9a5-4c413cd9943c",
"name": "Incoming Partner Usage Data",
"type": "n8n-nodes-base.webhook",
"position": [
-32,
-208
],
"parameters": {
"path": "a25d3181-6c3f-4014-bf85-ff07294f6ccc",
"options": {},
"httpMethod": "POST"
},
"typeVersion": 2.1
},
{
"id": "befba6e2-06d3-4d26-b054-d5468d0d5b46",
"name": "Sticky Note",
"type": "n8n-nodes-base.stickyNote",
"position": [
-96,
-352
],
"parameters": {
"color": 7,
"width": 688,
"height": 320,
"content": "## Incoming Partner Usage Data\nThis section receives incoming partner API usage data through a webhook and validates the payload structure and values. It ensures only correctly formatted and meaningful usage data is allowed to move forward in the workflow."
},
"typeVersion": 1
},
{
"id": "5628a036-369a-4877-a0fa-a577be2f6af2",
"name": "Sticky Note1",
"type": "n8n-nodes-base.stickyNote",
"position": [
656,
-352
],
"parameters": {
"color": 7,
"width": 528,
"height": 320,
"content": "## Analyze API Usage Levels\nThis section calculates the partner\u2019s API usage percentage based on allowed limits and checks whether the usage has crossed the defined alert threshold. It decides whether the situation requires internal review or no action."
},
"typeVersion": 1
},
{
"id": "88d9c56a-14a2-4104-a8ea-b1a287378cd0",
"name": "Sticky Note2",
"type": "n8n-nodes-base.stickyNote",
"position": [
1248,
-352
],
"parameters": {
"color": 7,
"width": 896,
"height": 320,
"content": "## 90% Usage Alert \u2013 Internal Review Trigger\nWhen API usage crosses 90% of the allocated quota, this section escalates the alert by creating a Jira ticket along with a Slack notification. It ensures internal teams initiate a formal review process and prepare for potential partner communication or plan adjustments."
},
"typeVersion": 1
},
{
"id": "bd9b0794-c87a-45a4-9beb-9399f2e5c7ed",
"name": "Sticky Note4",
"type": "n8n-nodes-base.stickyNote",
"position": [
-800,
-1088
],
"parameters": {
"width": 640,
"height": 688,
"content": "## How workflow works\n - Webhook receives partner API usage data (quota, consumed, partner details)\n - Payload is validated to ensure required fields are correct\n - Usage percentage is calculated from quota vs consumed\n - Switch node routes flow based on thresholds (80%, 90%, 100%)\n - 80%: Sends Slack alert for early warning\n - 90%: Sends Slack alert + creates Jira ticket for review\n - 100%: Sends Slack + Jira + Email for critical escalation\n - Ensures timely alerts, tracking and action to prevent service issues\n\n## Setup and Configuration Steps\n\n- Create webhook node to accept usage data\n- Add Code node to validate payload fields\n - Add Code node to calculate usage percentage\n - Configure Switch node for 80%, 90%, 100% conditions\n - Set up Slack node for notifications\n- Set up Jira node for ticket creation\n- Set up Gmail node for critical alerts\n - Add credentials for all integrations (Slack, Jira, Gmail)\n- Test with sample data to verify all scenarios\n- Deploy workflow after successful testing"
},
"typeVersion": 1
},
{
"id": "0fa05358-13ab-4c6e-b3a0-9bb8bf4b00f5",
"name": "Switch",
"type": "n8n-nodes-base.switch",
"position": [
960,
-224
],
"parameters": {
"rules": {
"values": [
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "5b691d97-8577-41c5-9818-65e338c28092",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.usage_pct }}",
"rightValue": 90
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "a4384c35-a05a-4310-a717-43ebc8efe400",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.usage_pct }}",
"rightValue": 80
}
]
}
},
{
"conditions": {
"options": {
"version": 2,
"leftValue": "",
"caseSensitive": true,
"typeValidation": "strict"
},
"combinator": "and",
"conditions": [
{
"id": "1eee6e83-d6ee-4036-9c2a-18f534a7832c",
"operator": {
"type": "number",
"operation": "gte"
},
"leftValue": "={{ $json.usage_pct }}",
"rightValue": 100
}
]
}
}
]
},
"options": {}
},
"typeVersion": 3.3
},
{
"id": "e5d72d3b-2ed7-476a-8535-0d0e46c845b1",
"name": "Send Slack Partner Usage Alert1",
"type": "n8n-nodes-base.slack",
"position": [
1664,
160
],
"parameters": {
"text": "=\ud83d\udea8 *Partner Usage Alert* \n*Partner:*{{ $('Validate Partner Usage Payload').item.json.partner_name }} \n*Usage:* {{Math.round($json[\"usage_pct\"])}}% \n*Plan:*{{ $('Validate Partner Usage Payload').item.json.plan }} \n*Timestamp:* {{ $('Validate Partner Usage Payload').item.json.timestamp }} \nRecommended Action: \n\u2022 Review the current plan tier\n\u2022 Consider reaching out for upgrade discussion.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C09S57E2JQ2",
"cachedResultName": "n8n"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "f9af8834-645e-4fe0-b4bb-e463216e3662",
"name": "Send a message",
"type": "n8n-nodes-base.gmail",
"position": [
1536,
624
],
"parameters": {
"sendTo": "",
"message": "==<!DOCTYPE html>\n<html>\n <body style=\"font-family: Arial, sans-serif; line-height: 1.6;\">\n \n <h2 style=\"color: #d9534f;\">\ud83d\udea8 API Usage Limit Reached</h2>\n \n <p><strong>Partner Name:</strong> {{$json[\"partner_name\"]}}</p>\n <p><strong>Partner ID:</strong> {{$json[\"partner_id\"]}}</p>\n <p><strong>Plan:</strong> {{$json[\"plan\"]}}</p>\n \n <hr>\n \n <p><strong>Quota:</strong> {{$json[\"quota\"]}}</p>\n <p><strong>Consumed:</strong> {{$json[\"consumed\"]}}</p>\n <p><strong>Usage:</strong> {{Math.round($json[\"usage_pct\"])}}%</p>\n \n <hr>\n\n <p><strong>Timestamp:</strong> {{$json[\"timestamp\"]}}</p>\n\n <h3 style=\"color: #f0ad4e;\">\u26a0 Recommended Action</h3>\n <ul>\n <li>Immediately review partner usage</li>\n <li>Contact partner for plan upgrade</li>\n <li>Prevent service disruption</li>\n </ul>\n\n <hr>\n\n <p style=\"color: #999;\">This is an automated alert from API Monitoring System</p>\n\n </body>\n</html>",
"options": {},
"subject": "== URGENT: {{$json[\"partner_name\"]}} has reached 100% API usage limit"
},
"credentials": {
"gmailOAuth2": {
"name": "<your credential>"
}
},
"typeVersion": 2.1
},
{
"id": "85ccdba5-23de-43a3-af90-9001811bd49b",
"name": "Create Jira Partner Review Ticket1",
"type": "n8n-nodes-base.jira",
"position": [
1712,
624
],
"parameters": {
"project": {
"__rl": true,
"mode": "list",
"value": "10000",
"cachedResultName": "n8n sample project"
},
"summary": "=Partner {{ $('Switch').item.json.partner_name }} reached {{ $('Switch').item.json.usage_pct }}% usage \u2013 Review Plan Tier",
"issueType": {
"__rl": true,
"mode": "list",
"value": "10003",
"cachedResultName": "Task"
},
"additionalFields": {
"description": "=Partner Usage Alert \nPartner Name:{{ $('Switch').item.json.partner_name }}\nPartner ID: {{ $('Switch').item.json.partner_id }}\nPlan: {{ $('Switch').item.json.plan }}\nQuota: {{ $('Switch').item.json.quota }}\nConsumed: {{ $('Switch').item.json.consumed }}\nUsage %: {{ $('Switch').item.json.usage_pct }}\nTimestamp: {{ $('Switch').item.json.timestamp }}\nRecommended Action: - Review current plan tier. - Contact partner for possible upgrade discussion."
}
},
"credentials": {
"jiraSoftwareCloudApi": {
"name": "<your credential>"
}
},
"typeVersion": 1
},
{
"id": "80d137a7-3076-4159-9142-362d81ab1c35",
"name": "Send Slack Partner Usage Alert2",
"type": "n8n-nodes-base.slack",
"position": [
1872,
624
],
"parameters": {
"text": "=\ud83d\udea8 *Partner Usage Alert* \n*Partner:*{{ $('Validate Partner Usage Payload').item.json.partner_name }} \n*Usage:* {{Math.round($json[\"usage_pct\"])}}% \n*Plan:*{{ $('Validate Partner Usage Payload').item.json.plan }} \n*Timestamp:* {{ $('Validate Partner Usage Payload').item.json.timestamp }} \n*A Jira ticket has been created for review:* {{ $json.key }} \nRecommended Action: \n\u2022 Review the current plan tier\n\u2022 Consider reaching out for upgrade discussion.",
"select": "channel",
"channelId": {
"__rl": true,
"mode": "list",
"value": "C09S57E2JQ2",
"cachedResultName": "n8n"
},
"otherOptions": {}
},
"credentials": {
"slackApi": {
"name": "<your credential>"
}
},
"typeVersion": 2.3
},
{
"id": "c137bc68-778c-4e2b-8bff-f770a0b3c4da",
"name": "Sticky Note5",
"type": "n8n-nodes-base.stickyNote",
"position": [
1248,
16
],
"parameters": {
"color": 7,
"width": 912,
"height": 384,
"content": "## 80% Usage Alert \u2013 Early Warning Notification\nThis section monitors when a partner reaches 80% of their API usage quota. It acts as an early warning system by sending a Slack notification to internal teams, enabling proactive monitoring and giving sufficient time to assess usage trends before critical limits are reached."
},
"typeVersion": 1
},
{
"id": "28e96297-85e3-4d3e-9dff-f33acee1e7fd",
"name": "Sticky Note3",
"type": "n8n-nodes-base.stickyNote",
"position": [
1248,
464
],
"parameters": {
"color": 7,
"width": 912,
"height": 336,
"content": "## 100% Usage Alert \u2013 Critical Escalation & Action Required\nThis section handles critical scenarios where a partner fully exhausts their API quota. It triggers immediate escalation by sending an email, creating a Jira ticket and notifying via Slack, ensuring rapid response to prevent service disruption and initiate urgent upgrade or mitigation actions."
},
"typeVersion": 1
}
],
"active": false,
"settings": {
"executionOrder": "v1"
},
"versionId": "cfc8118e-c5a8-4d37-bb61-f8e46ea7cc86",
"connections": {
"Switch": {
"main": [
[
{
"node": "Create Jira Partner Review Ticket",
"type": "main",
"index": 0
}
],
[
{
"node": "Send Slack Partner Usage Alert1",
"type": "main",
"index": 0
}
],
[
{
"node": "Send a message",
"type": "main",
"index": 0
}
]
]
},
"Send a message": {
"main": [
[
{
"node": "Create Jira Partner Review Ticket1",
"type": "main",
"index": 0
}
]
]
},
"Is Usage Payload Valid?": {
"main": [
[
{
"node": "Calculate API Usage Percentage",
"type": "main",
"index": 0
}
]
]
},
"Incoming Partner Usage Data": {
"main": [
[
{
"node": "Validate Partner Usage Payload",
"type": "main",
"index": 0
}
]
]
},
"Calculate API Usage Percentage": {
"main": [
[
{
"node": "Switch",
"type": "main",
"index": 0
}
]
]
},
"Validate Partner Usage Payload": {
"main": [
[
{
"node": "Is Usage Payload Valid?",
"type": "main",
"index": 0
}
]
]
},
"Create Jira Partner Review Ticket": {
"main": [
[
{
"node": "Send Slack Partner Usage Alert",
"type": "main",
"index": 0
}
]
]
},
"Create Jira Partner Review Ticket1": {
"main": [
[
{
"node": "Send Slack Partner Usage Alert2",
"type": "main",
"index": 0
}
]
]
}
}
}
Credentials you'll need
Each integration node will prompt for credentials when you import. We strip credential IDs before publishing — you'll add your own.
gmailOAuth2jiraSoftwareCloudApislackApi
For the full experience including quality scoring and batch install features for each workflow upgrade to Pro
About this workflow
This workflow monitors partner API usage in real time and triggers alerts based on usage thresholds. It validates incoming data, calculates usage percentage and routes actions using a Switch node. Slack notifications are sent at 80%, Jira tickets are created at 90% and critical…
Source: https://n8n.io/workflows/14709/ — 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.
Receive booking requests via webhook with automatic validation, duplicate detection, availability checking, confirmation emails, Google Calendar sync, and Slack notifications.
This template is designed for freelancers, small businesses, and finance teams who need automated invoice management with intelligent payment follow-ups. Perfect for service providers, agencies, or an
Automate short-term trading research by generating high-quality trade ideas using MCP (Market Context Protocol) signals and AI-powered analysis. 📈🤖 This workflow evaluates market context, catalysts, m
Who’s it for
Automate building visitor management with secure verification, digital entry passes, and real-time security notifications.