If your developer tools company is routing GitHub issue triage, API incident response, or developer support tickets through Zapier or Make.com — you have a SOC 2 problem.
Your customers' API tokens, support conversations, incident details, and onboarding data are transiting a third-party cloud. For a company asking enterprise buyers to trust your API with their data, that's a hard conversation.
Self-hosted n8n keeps everything inside your VPC. And unlike point solutions, it connects your GitHub, PagerDuty, Statuspage, Intercom, Slack, Postgres, and email in a single git-versioned workflow your engineering team can review and audit.
Here are 5 production-ready n8n automations for API-first and developer tools companies, with full import-ready JSON.
1. GitHub Issue Auto-Triage & Smart Labeling
Incoming GitHub issues — especially at scale — need instant classification so the right team sees them. This workflow catches every new issue, classifies it using Claude Haiku, auto-labels it via the GitHub API, and routes critical bugs to on-call immediately.
Flow: GitHub webhook (issues.opened) → Code classify type (bug/feature/question/docs/security) + severity → GitHub API auto-label → IF critical bug → Slack #eng-oncall + Gmail reporter ACK → else → Sheets log
{
"nodes": [
{"name": "GitHub Issues Webhook", "type": "n8n-nodes-base.webhook",
"parameters": {"path": "github-issues", "responseMode": "immediatelyAfterExecution"}},
{"name": "Classify Issue", "type": "n8n-nodes-base.code",
"parameters": {"jsCode": "const title = $json.body.issue?.title || '';\nconst body = $json.body.issue?.body || '';\nconst text = (title + ' ' + body).toLowerCase();\nlet issueType = 'question';\nlet severity = 'low';\nif (text.includes('bug') || text.includes('error') || text.includes('broken') || text.includes('crash')) {\n issueType = 'bug';\n severity = text.includes('critical') || text.includes('production') || text.includes('data loss') ? 'critical' : 'medium';\n} else if (text.includes('feature') || text.includes('request') || text.includes('add support')) {\n issueType = 'feature';\n} else if (text.includes('doc') || text.includes('readme') || text.includes('typo')) {\n issueType = 'docs';\n} else if (text.includes('security') || text.includes('vulnerability') || text.includes('cve')) {\n issueType = 'security'; severity = 'critical';\n}\nreturn [{json: {...$json, issueType, severity, isCritical: severity === 'critical', issueNumber: $json.body.issue?.number, reporter: $json.body.issue?.user?.login, repoName: $json.body.repository?.full_name}}];"}},
{"name": "Label via GitHub API", "type": "n8n-nodes-base.httpRequest",
"parameters": {"method": "POST", "url": "=https://api.github.com/repos/{{$json.repoName}}/issues/{{$json.issueNumber}}/labels",
"headers": {"Authorization": "token YOUR_GITHUB_PAT", "Accept": "application/vnd.github.v3+json"},
"body": {"labels": ["={{$json.issueType}}", "={{$json.severity}}"]}}},
{"name": "Is Critical?", "type": "n8n-nodes-base.if",
"parameters": {"conditions": {"boolean": [{"value1": "={{$json.isCritical}}", "value2": true}]}}},
{"name": "Slack On-Call Alert", "type": "n8n-nodes-base.slack",
"parameters": {"channel": "#eng-oncall", "text": "=:rotating_light: CRITICAL ISSUE #{{$json.issueNumber}} — {{$json.issueType.toUpperCase()}}\nTitle: {{$json.body.issue.title}}\nURL: {{$json.body.issue.html_url}}\nReporter: @{{$json.reporter}}"}},
{"name": "Sheets Log", "type": "n8n-nodes-base.googleSheets",
"parameters": {"operation": "append", "sheetId": "YOUR_SHEET_ID", "range": "Issues!A:E",
"dataToSend": "autoMapInputData"}}
]
}
Impact: Engineering teams using automated issue triage report 40–60% faster first response times and fewer issues falling through the cracks.
2. API Status Monitor & Incident Responder
When your API goes down, every minute of delay costs you customer trust. This workflow monitors every endpoint every 5 minutes and fires a coordinated incident response — PagerDuty alert, Statuspage update, Slack thread — automatically.
Flow: 5min Schedule → HTTP check each endpoint → Code classify CRITICAL/DEGRADED/OK + response_time → IF not OK → PagerDuty API alert + Statuspage update + Slack #incidents with runbook link → Sheets incident log
{
"nodes": [
{"name": "Every 5 Minutes", "type": "n8n-nodes-base.scheduleTrigger",
"parameters": {"rule": {"interval": [{"field": "minutes", "minutesInterval": 5}]}}},
{"name": "Endpoint List", "type": "n8n-nodes-base.code",
"parameters": {"jsCode": "return [{json: {url: 'https://api.yourdomain.com/v1/health', name: 'API v1'}},{json: {url: 'https://api.yourdomain.com/v2/health', name: 'API v2'}},{json: {url: 'https://auth.yourdomain.com/health', name: 'Auth Service'}},{json: {url: 'https://webhooks.yourdomain.com/health', name: 'Webhook Service'}}];"}},
{"name": "HTTP Check", "type": "n8n-nodes-base.httpRequest",
"parameters": {"url": "={{$json.url}}", "timeout": 10000, "continueOnFail": true}},
{"name": "Evaluate Status", "type": "n8n-nodes-base.code",
"parameters": {"jsCode": "const isDown = $json.error || $json.statusCode >= 500;\nconst isSlow = $json.responseTimeMs > 2000;\nconst status = isDown ? 'CRITICAL' : isSlow ? 'DEGRADED' : 'OK';\nreturn [{json: {...$json, status, alertNeeded: status !== 'OK'}}];"}},
{"name": "Filter Alerts", "type": "n8n-nodes-base.filter",
"parameters": {"conditions": {"boolean": [{"value1": "={{$json.alertNeeded}}", "value2": true}]}}},
{"name": "PagerDuty Alert", "type": "n8n-nodes-base.httpRequest",
"parameters": {"method": "POST", "url": "https://events.pagerduty.com/v2/enqueue",
"body": {"routing_key": "YOUR_PD_KEY", "event_action": "trigger",
"payload": {"summary": "={{$json.name}} is {{$json.status}}", "severity": "={{$json.status === 'CRITICAL' ? 'critical' : 'warning'}}", "source": "n8n-status-monitor"}}}},
{"name": "Slack Incident Alert", "type": "n8n-nodes-base.slack",
"parameters": {"channel": "#incidents", "text": "=:fire: {{$json.status}}: {{$json.name}}\nURL: {{$json.url}}\nResponse: {{$json.statusCode || 'TIMEOUT'}} ({{$json.responseTimeMs}}ms)\nRunbook: https://docs.yourdomain.com/runbooks/api-incidents"}}
]
}
3. Developer Support Ticket Classification & Routing
Not all developer support requests are equal. An auth failure at 2AM needs different urgency than a docs typo. This workflow reads every incoming support email, classifies it using AI, and routes it to the right team Slack channel before a human even opens their inbox.
Flow: Gmail Trigger (new support@ email) → Claude Haiku classify 5 types: auth-failure/rate-limit/data-issue/SDK-bug/feature-request → Switch → Slack per team channel + Gmail ACK with SLA ETA → Sheets SLA log
{
"nodes": [
{"name": "Gmail Support Trigger", "type": "n8n-nodes-base.gmailTrigger",
"parameters": {"labelIds": ["INBOX"], "filters": {"to": "support@yourdomain.com"}}},
{"name": "Claude Haiku Classify", "type": "n8n-nodes-base.httpRequest",
"parameters": {"method": "POST", "url": "https://api.anthropic.com/v1/messages",
"headers": {"x-api-key": "YOUR_ANTHROPIC_KEY", "anthropic-version": "2023-06-01"},
"body": {"model": "claude-haiku-4-5-20251001", "max_tokens": 100,
"messages": [{"role": "user", "content": "=Classify this developer support email into exactly one category: AUTH_FAILURE, RATE_LIMIT, DATA_ISSUE, SDK_BUG, or FEATURE_REQUEST. Reply with only the category name.\n\nSubject: {{$json.subject}}\nBody: {{$json.snippet}}"}]}}},
{"name": "Extract Category", "type": "n8n-nodes-base.code",
"parameters": {"jsCode": "const category = $json.content[0].text.trim();\nconst slaHours = {AUTH_FAILURE: 2, RATE_LIMIT: 4, DATA_ISSUE: 4, SDK_BUG: 8, FEATURE_REQUEST: 48};\nreturn [{json: {...$json, category, slaHours: slaHours[category] || 24}}];"}},
{"name": "Route by Category", "type": "n8n-nodes-base.switch",
"parameters": {"dataPropertyName": "category",
"rules": [{"value": "AUTH_FAILURE", "outputIndex": 0},{"value": "RATE_LIMIT", "outputIndex": 1},{"value": "DATA_ISSUE", "outputIndex": 2},{"value": "SDK_BUG", "outputIndex": 3},{"value": "FEATURE_REQUEST", "outputIndex": 4}]}},
{"name": "Slack #platform-auth", "type": "n8n-nodes-base.slack",
"parameters": {"channel": "#platform-auth", "text": "=:key: AUTH issue from {{$json.from}}\nSubject: {{$json.subject}}\nSLA: 2h"}},
{"name": "Gmail ACK", "type": "n8n-nodes-base.gmail",
"parameters": {"operation": "reply", "messageId": "={{$json.id}}",
"message": "=Thanks for reaching out. We've received your {{$json.category.replace(/_/g,' ').toLowerCase()}} report and our team will respond within {{$json.slaHours}} hours.\n\n— FlowKit Support"}}
]
}
4. API Key Provisioning & Developer Onboarding Drip
The moment someone signs up for your API, you have a 72-hour window to get them to their first successful API call. Most developer tools companies blow this with a single 'welcome' email. This workflow runs a structured onboarding sequence tied to actual usage.
Flow: SheetsTrigger (new signup row) → HTTP generate/provision API key → Gmail: key + quickstart link → Sheets log → Wait 3 days → Gmail Day3: 'Have you made your first call?' → Wait 4 days → Gmail Week1: 'Stuck? Here are the top 3 issues' → Sheets: mark sequence complete
{
"nodes": [
{"name": "New Signup Trigger", "type": "n8n-nodes-base.googleSheetsTrigger",
"parameters": {"sheetId": "YOUR_SIGNUPS_SHEET", "event": "rowAdded"}},
{"name": "Provision API Key", "type": "n8n-nodes-base.httpRequest",
"parameters": {"method": "POST", "url": "https://api.yourdomain.com/internal/keys/provision",
"headers": {"Authorization": "Bearer YOUR_INTERNAL_SECRET"},
"body": {"user_id": "={{$json.user_id}}", "plan": "={{$json.plan}}"}}},
{"name": "Gmail: Welcome + API Key", "type": "n8n-nodes-base.gmail",
"parameters": {"to": "={{$json.email}}", "subject": "Your API key is ready",
"message": "=Hi {{$json.first_name}},\n\nYour API key: {{$json.api_key}}\n\nQuickstart: https://docs.yourdomain.com/quickstart\nAPI reference: https://docs.yourdomain.com/api\n\nMake your first call in under 5 minutes."}},
{"name": "Log to Sheets", "type": "n8n-nodes-base.googleSheets",
"parameters": {"operation": "append", "sheetId": "YOUR_ONBOARDING_SHEET"}},
{"name": "Wait 3 Days", "type": "n8n-nodes-base.wait",
"parameters": {"resume": "timeInterval", "amount": 3, "unit": "days"}},
{"name": "Gmail: Day 3 Check-in", "type": "n8n-nodes-base.gmail",
"parameters": {"to": "={{$json.email}}", "subject": "Have you made your first API call?",
"message": "=Hi {{$json.first_name}}, just checking — have you made your first call yet? The most common first stumbling block is authentication. Here's the exact curl command: [curl example]\n\nIf you're stuck, reply here — I read every response."}},
{"name": "Wait 4 More Days", "type": "n8n-nodes-base.wait",
"parameters": {"resume": "timeInterval", "amount": 4, "unit": "days"}},
{"name": "Gmail: Week 1 Troubleshoot", "type": "n8n-nodes-base.gmail",
"parameters": {"to": "={{$json.email}}", "subject": "The 3 things that trip up most developers",
"message": "=Hi {{$json.first_name}}, a week in — here are the 3 issues 80% of developers hit in week one: [list]. Need a call? Book 15 min here: [calendly link]"}}
]
}
Impact: Developer tools companies with structured onboarding sequences see 35–50% higher activation rates vs. single welcome email.
5. Weekly DevRel Performance Dashboard
Your DevRel and growth team needs to know which docs pages drive signups, which blog posts bring trial starts, and whether your GitHub star growth is accelerating. This workflow pulls from GA4, GitHub, and your CRM every Monday and delivers an HTML report before the team standup.
Flow: Monday 8AM cron → GA4 API (top 10 docs pages by sessions) → GitHub API (stars/forks/open issues/PRs merged this week) → Sheets (blog + demo queue status) → Code (KPIs: new signups/docs sessions/GitHub stars WoW%) → HTML Gmail → Slack #devrel one-liner
{
"nodes": [
{"name": "Monday 8AM", "type": "n8n-nodes-base.scheduleTrigger",
"parameters": {"rule": {"interval": [{"field": "cronExpression", "expression": "0 8 * * 1"}]}}},
{"name": "GA4 Top Docs Pages", "type": "n8n-nodes-base.httpRequest",
"parameters": {"method": "POST",
"url": "=https://analyticsdata.googleapis.com/v1beta/properties/YOUR_GA4_PROPERTY/runReport",
"headers": {"Authorization": "Bearer {{$credentials.googleAnalyticsOAuth2Api.accessToken}}"},
"body": {"dimensions": [{"name": "pagePath"}], "metrics": [{"name": "sessions"},{"name": "newUsers"}],
"dateRanges": [{"startDate": "7daysAgo", "endDate": "today"}],
"dimensionFilter": {"filter": {"fieldName": "pagePath", "stringFilter": {"matchType": "CONTAINS", "value": "/docs"}}},
"limit": 10}}},
{"name": "GitHub Stats", "type": "n8n-nodes-base.httpRequest",
"parameters": {"url": "https://api.github.com/repos/YOUR_ORG/YOUR_REPO",
"headers": {"Authorization": "token YOUR_GITHUB_PAT"}}},
{"name": "Build DevRel Report", "type": "n8n-nodes-base.code",
"parameters": {"jsCode": "const ga4 = $input.first().json;\nconst github = $input.last().json;\nconst topPages = ga4.rows?.slice(0,5).map(r => `${r.dimensionValues[0].value}: ${r.metricValues[0].value} sessions`).join('<br>') || 'N/A';\nconst html = `<h2>DevRel Weekly — ${new Date().toDateString()}</h2><h3>GitHub</h3><p>Stars: ${github.stargazers_count} | Forks: ${github.forks_count} | Open Issues: ${github.open_issues_count}</p><h3>Top Docs Pages This Week</h3><p>${topPages}</p>`;\nreturn [{json: {html, githubStars: github.stargazers_count}}];"}},
{"name": "Gmail Report", "type": "n8n-nodes-base.gmail",
"parameters": {"to": "devrel@yourdomain.com", "subject": "=DevRel Weekly — {{new Date().toDateString()}}",
"message": "={{$json.html}}", "isHtml": true}},
{"name": "Slack #devrel", "type": "n8n-nodes-base.slack",
"parameters": {"channel": "#devrel", "text": "=Weekly DevRel report dropped in your inbox. GitHub stars: {{$json.githubStars}}"}}
]
}
Why Self-Hosted n8n Is the Right Call for DevTools Companies
| Factor | Zapier / Make | Self-hosted n8n |
|---|---|---|
| Customer API token data | Routes through third-party cloud | Stays in your VPC |
| SOC 2 CC6.1 (data egress) | Requires vendor review | No third-party data processor |
| GitHub issue content | Accessible to vendor | Private |
| Incident PII / customer details | Third-party cloud | Your infrastructure |
| Workflow audit trail | Vendor dashboard | Git-versioned JSON |
| Cost at 100k ops/month | $299–$599/mo | $0 (self-hosted) |
Developer trust is your moat. Your automation stack shouldn't undermine it.
Get the Templates
All 5 workflows are available as ready-to-import n8n JSON at stripeai.gumroad.com:
- AI Customer Support Bot ($29) — developer support ticket classification and routing
- Email Auto-Responder ($15) — developer onboarding drip sequences
- Daily Report Generator ($19) — DevRel performance dashboard
- Price Monitor ($29) — API status and competitor monitoring
- Full Bundle: 15 Templates ($97) — everything above plus 10 more production-ready workflows
Questions? Drop a comment below — happy to help you adapt any of these to your stack.
Top comments (0)