{
  "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
          }
        ]
      ]
    }
  }
}