DEV Community

Alex Kane
Alex Kane

Posted on

n8n for Logistics SaaS Companies: 5 Automations That Scale Customer Ops Without Headcount (Free Workflow JSON)

If you're building a logistics SaaS platform — TMS, WMS, last-mile delivery software, carrier aggregator — your ops team is drowning in reactive work: onboarding new shippers, firefighting carrier API outages, triaging integration tickets, manually building weekly reports.

n8n fixes this. It's open-source, self-hostable, and has native connectors for Postgres, Slack, Gmail, HTTP APIs, and webhooks. For logistics SaaS specifically, self-hosting is non-negotiable: carrier rate cards, shipper lane data, and route optimization models are commercially sensitive trade secrets that cannot transit Zapier or Make's cloud.

Here are 5 production-ready workflows that logistics SaaS teams are running today.


1. New Customer Onboarding & Integration Drip

Every new shipper needs the same 5 things: welcome email, API credentials, integration guide, Day 3 health check, Week 1 feature nudge. Manual = slow and inconsistent.

{
  "nodes": [
    {"type": "n8n-nodes-base.googleSheetsTrigger", "parameters": {"event": "rowAdded", "sheetId": "NEW_ACCOUNTS_SHEET"}, "name": "New Account"},
    {"type": "n8n-nodes-base.gmail", "parameters": {"subject": "Welcome to {{$json.company_name}} — your API credentials", "body": "Here is your API key: {{$json.api_key}}..."}, "name": "Welcome Email"},
    {"type": "n8n-nodes-base.wait", "parameters": {"amount": 3, "unit": "days"}, "name": "Wait 3d"},
    {"type": "n8n-nodes-base.gmail", "parameters": {"subject": "Quick check-in: integration going well?", "body": "Hi {{$json.contact_name}}, just checking if the integration is live..."}, "name": "Day 3 Check-in"},
    {"type": "n8n-nodes-base.wait", "parameters": {"amount": 4, "unit": "days"}, "name": "Wait 4d"},
    {"type": "n8n-nodes-base.gmail", "parameters": {"subject": "3 features most shippers activate in week 1", "body": "{{$json.contact_name}}, here are the 3 features that drive the fastest ROI..."}, "name": "Week 1 Feature Email"},
    {"type": "n8n-nodes-base.googleSheets", "parameters": {"operation": "update", "sheetId": "NEW_ACCOUNTS_SHEET", "data": {"onboarding_status": "complete"}}, "name": "Mark Complete"}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Why it works: Onboarding speed directly predicts 90-day retention. Automating the drip frees your CSM to focus on at-risk accounts, not copy-pasting welcome emails.


2. Carrier API Health Monitor & Customer Alert

When a carrier API goes down, your shippers start getting errors. The first person who should know is your NOC — not your customers' support queues.

{
  "nodes": [
    {"type": "n8n-nodes-base.scheduleTrigger", "parameters": {"rule": {"interval": [{"field": "minutes", "minutesInterval": 5}]}}, "name": "Every 5 min"},
    {"type": "n8n-nodes-base.googleSheets", "parameters": {"operation": "getAll", "sheetId": "CARRIER_ENDPOINTS"}, "name": "Get Carrier List"},
    {"type": "n8n-nodes-base.httpRequest", "parameters": {"url": "={{$json.health_url}}", "timeout": 5000}, "name": "Health Check"},
    {"type": "n8n-nodes-base.code", "parameters": {"jsCode": "const results = $input.all(); return results.filter(r => r.json.statusCode !== 200 || r.json.responseTime > 3000).map(r => ({...r.json, status: r.json.statusCode !== 200 ? 'DOWN' : 'DEGRADED'}));"}, "name": "Flag Issues"},
    {"type": "n8n-nodes-base.if", "parameters": {"conditions": {"number": [{"value1": "={{$items().length}}", "operation": "larger", "value2": 0}]}}, "name": "Issues Found?"},
    {"type": "n8n-nodes-base.slack", "parameters": {"channel": "#integrations-noc", "text": "CARRIER DOWN: {{$json.carrier_name}} — {{$json.status}} since {{$now.toISO()}}"}, "name": "Slack NOC"},
    {"type": "n8n-nodes-base.postgres", "parameters": {"operation": "insert", "table": "carrier_sla_log", "data": {"carrier": "={{$json.carrier_name}}", "status": "={{$json.status}}", "detected_at": "={{$now.toISO()}}"}}, "name": "Log Incident"}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Why it works: Most carrier APIs have 99.5% uptime — meaning ~44 hours of downtime per year. Each incident caught within 5 minutes instead of 30 saves dozens of customer support tickets.


3. Support Ticket Auto-Triage & SLA Routing

Logistics SaaS support tickets cluster around 4 types: carrier failures, billing questions, feature requests, and data sync issues. Route them instantly to the right team with auto-acknowledged SLA promises.

{
  "nodes": [
    {"type": "n8n-nodes-base.webhook", "parameters": {"path": "support-ticket", "responseMode": "responseNode"}, "name": "Ticket Webhook"},
    {"type": "n8n-nodes-base.respondToWebhook", "parameters": {"responseCode": 200, "responseBody": "{\"received\": true}"}, "name": "Immediate ACK"},
    {"type": "n8n-nodes-base.code", "parameters": {"jsCode": "const t = $json.subject.toLowerCase() + ' ' + $json.body.toLowerCase(); let type = 'GENERAL', sla = 48; if (/carrier|api.down|rate.error|tracking/.test(t)) { type = 'CARRIER_ISSUE'; sla = 4; } else if (/billing|invoice|charge|refund/.test(t)) { type = 'BILLING'; sla = 24; } else if (/feature|request|roadmap/.test(t)) { type = 'FEATURE_REQ'; sla = 72; } else if (/sync|webhook|import|export/.test(t)) { type = 'DATA_SYNC'; sla = 8; } return [{...($json), ticket_type: type, sla_hours: sla}];"}, "name": "Classify"},
    {"type": "n8n-nodes-base.switch", "parameters": {"rules": {"rules": [{"value": "CARRIER_ISSUE", "output": 0}, {"value": "BILLING", "output": 1}, {"value": "DATA_SYNC", "output": 2}, {"value": "FEATURE_REQ", "output": 3}]}}, "name": "Route"},
    {"type": "n8n-nodes-base.slack", "parameters": {"channel": "#carrier-ops", "text": "CARRIER TICKET: {{$json.subject}} from {{$json.company}} — SLA 4h"}, "name": "Carrier Team Slack"},
    {"type": "n8n-nodes-base.gmail", "parameters": {"to": "={{$json.from_email}}", "subject": "Re: {{$json.subject}} — we're on it", "body": "Hi {{$json.contact_name}}, we've received your ticket and our team will respond within {{$json.sla_hours}} hours..."}, "name": "ACK Email"},
    {"type": "n8n-nodes-base.googleSheets", "parameters": {"operation": "append", "sheetId": "TICKET_LOG", "data": {"ticket_id": "={{$json.id}}", "type": "={{$json.ticket_type}}", "sla": "={{$json.sla_hours}}", "created": "={{$now.toISO()}}"}}, "name": "Log Ticket"}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Why it works: Carrier integration tickets need 4-hour SLAs; feature requests can wait 72 hours. Mixing them in one queue means carrier fires get buried. Auto-routing cuts mean response time by ~60%.


4. Customer Churn Early Warning System

By the time a shipper submits a cancellation, you've already lost them. The signal was in the data 3-4 weeks earlier: login drops, API call drops, support ticket spikes.

{
  "nodes": [
    {"type": "n8n-nodes-base.scheduleTrigger", "parameters": {"rule": {"interval": [{"field": "cronExpression", "expression": "0 8 * * 1-5"}]}}, "name": "Weekdays 8AM"},
    {"type": "n8n-nodes-base.postgres", "parameters": {"operation": "executeQuery", "query": "SELECT account_id, company_name, csm_email, logins_last_7d, api_calls_last_7d, logins_prev_7d, api_calls_prev_7d, open_tickets, renewal_days_out FROM account_health_view WHERE contract_status = 'active'"}, "name": "Get Account Health"},
    {"type": "n8n-nodes-base.code", "parameters": {"jsCode": "return $input.all().map(item => { const d = item.json; let score = 100; if (d.logins_prev_7d > 0) { const loginDrop = (d.logins_prev_7d - d.logins_last_7d) / d.logins_prev_7d; if (loginDrop > 0.5) score -= 25; else if (loginDrop > 0.25) score -= 15; } if (d.api_calls_prev_7d > 0) { const apiDrop = (d.api_calls_prev_7d - d.api_calls_last_7d) / d.api_calls_prev_7d; if (apiDrop > 0.5) score -= 30; else if (apiDrop > 0.25) score -= 15; } if (d.open_tickets > 3) score -= 20; else if (d.open_tickets > 1) score -= 10; if (d.renewal_days_out < 30) score -= 15; else if (d.renewal_days_out < 60) score -= 5; const tier = score < 40 ? 'RED' : score < 65 ? 'AMBER' : 'GREEN'; return { json: { ...d, health_score: score, tier } }; }).filter(i => i.json.tier !== 'GREEN');"}, "name": "Score Accounts"},
    {"type": "n8n-nodes-base.if", "parameters": {"conditions": {"string": [{"value1": "={{$json.tier}}", "operation": "equal", "value2": "RED"}]}}, "name": "RED?"},
    {"type": "n8n-nodes-base.slack", "parameters": {"channel": "={{$json.csm_slack_id}}", "text": "CHURN RISK RED: {{$json.company_name}} score {{$json.health_score}} — renewal in {{$json.renewal_days_out}}d. Logins: {{$json.logins_last_7d}} (was {{$json.logins_prev_7d}}). API: {{$json.api_calls_last_7d}} (was {{$json.api_calls_prev_7d}})."}, "name": "DM CSM RED"},
    {"type": "n8n-nodes-base.slack", "parameters": {"channel": "#cs-watch-list", "text": "AMBER: {{$json.company_name}} score {{$json.health_score}}"}, "name": "Slack AMBER"}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Why it works: Composite scoring (login drop + API drop + ticket volume + renewal proximity) catches churn signals that any single metric misses. RED accounts get a direct CSM DM so nothing falls through the cracks.


5. Weekly Platform KPI Report

Every Monday at 8 AM, your leadership team should have a single HTML email with the numbers that matter: shipments processed, on-time delivery rate, carrier uptime, new accounts, MRR, churn.

{
  "nodes": [
    {"type": "n8n-nodes-base.scheduleTrigger", "parameters": {"rule": {"interval": [{"field": "cronExpression", "expression": "0 8 * * 1"}]}}, "name": "Monday 8AM"},
    {"type": "n8n-nodes-base.postgres", "parameters": {"operation": "executeQuery", "query": "SELECT SUM(shipments_processed) as shipments, ROUND(AVG(ontime_pct)*100,1) as ontime_pct, ROUND(AVG(carrier_uptime_pct)*100,2) as carrier_uptime, COUNT(DISTINCT CASE WHEN created_at > NOW()-INTERVAL '7 days' THEN account_id END) as new_accounts, SUM(mrr_usd) as mrr, COUNT(DISTINCT CASE WHEN churned_at > NOW()-INTERVAL '7 days' THEN account_id END) as churned FROM weekly_platform_stats WHERE week_start = DATE_TRUNC('week', NOW()-INTERVAL '7 days')"}, "name": "Get KPIs"},
    {"type": "n8n-nodes-base.code", "parameters": {"jsCode": "const d = $json; const html = `<h2>Platform KPIs — Week of ${new Date().toDateString()}</h2><table border='1' cellpadding='8'><tr><td>Shipments Processed</td><td>${d.shipments?.toLocaleString()}</td></tr><tr><td>On-Time Delivery</td><td>${d.ontime_pct}%</td></tr><tr><td>Carrier Uptime</td><td>${d.carrier_uptime}%</td></tr><tr><td>New Accounts</td><td>${d.new_accounts}</td></tr><tr><td>MRR</td><td>$${parseInt(d.mrr)?.toLocaleString()}</td></tr><tr><td>Churned</td><td>${d.churned}</td></tr></table>`; return [{json: {html}}];"}, "name": "Build HTML"},
    {"type": "n8n-nodes-base.gmail", "parameters": {"to": "ceo@yourcompany.com", "bcc": "vp-product@yourcompany.com,vp-eng@yourcompany.com", "subject": "Platform KPIs — {{$now.format('MMM D, YYYY')}}", "htmlBody": "={{$json.html}}"}, "name": "Send Report"},
    {"type": "n8n-nodes-base.slack", "parameters": {"channel": "#go-to-market", "text": "Weekly KPIs: {{$json.shipments}} shipments | {{$json.ontime_pct}}% on-time | ${{$json.mrr}} MRR | {{$json.new_accounts}} new accounts | {{$json.churned}} churned"}, "name": "Slack Summary"}
  ]
}
Enter fullscreen mode Exit fullscreen mode

Why it works: Leadership stops asking "where are we?" via Slack threads. One scheduled email = one source of truth every Monday.


Why self-hosted n8n for logistics SaaS

Factor n8n (self-hosted) Zapier Make.com
Shipper data stays in your VPC ✅ Yes ❌ Routes through cloud ❌ Routes through cloud
Carrier rate cards stay private ✅ Yes ❌ Zapier can see payloads ❌ Make can see payloads
Cost at 500K ops/month $0 (self-hosted) $599/mo $299/mo
Workflow version control ✅ Git JSON ❌ None ❌ None
Runs inside your SOC2 boundary ✅ Yes ❌ No ❌ No
Carrier API polling (sub-1min) ✅ Yes ❌ 1min min ✅ 1min min

Get the complete workflow pack

All 5 workflows above are available as import-ready JSON in the FlowKit n8n Automation Templates store — ready to copy into your n8n instance in under 5 minutes.

Individual templates: $12–$29. Full bundle (13 templates): $97.

Built anything cool with n8n for logistics or SaaS ops? Share it in the comments — I'd love to see it.

Top comments (0)