DEV Community

Alex Kane
Alex Kane

Posted on

n8n for LogisticsTech SaaS: 5 Automations for FMCSA, CBP Customs, IATA CASS, and Supply Chain Compliance (Free Workflow JSON)

If your company sells WMS, TMS, ELD, or last-mile delivery software, your platform handles data that's subject to FMCSA Hours of Service rules, CBP Automated Export System filings, IATA CASS cargo billing settlements, and — since 2022 — EU Supply Chain Due Diligence obligations.

Most LogisticsTech teams rely on Zapier or Make to wire their internal ops together. That's a compliance gap hiding in plain sight.

FMCSA doesn't care that your ELD data is flowing through a third-party iPaaS. CBP does care when AES filing data (Schedule B commodity codes, declared value, shipper/consignee identity) transits external servers. And if you're handling HAZMAT tracking data under 49 CFR HMR, you have recordkeeping obligations that a Zapier automation log won't satisfy.

Self-hosted n8n keeps all that data in your own infrastructure. Here are 5 workflows built specifically for LogisticsTech SaaS vendors.


Workflow 1: New Carrier/Shipper Customer Onboarding Drip

Different customers have different compliance profiles. A HAZMAT carrier needs different onboarding content than a same-day delivery startup.

Trigger: Webhook (new customer signed up)

{
  "name": "LogisticsTech Customer Onboarding Drip",
  "nodes": [
    {
      "name": "Webhook Trigger",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "parameters": {
        "httpMethod": "POST",
        "path": "logisticstech-onboard"
      },
      "position": [
        240,
        300
      ]
    },
    {
      "name": "Extract & Classify Customer",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "parameters": {
        "jsCode": "const body = $input.first().json.body || $input.first().json;\nconst plan = (body.plan || '').toUpperCase();\nconst flags = body.compliance_flags || [];\nlet tier = 'SMB_CARRIER';\nif (plan.includes('ENTERPRISE') || (body.fleet_size || 0) >= 500) tier = 'MEGA_BROKER';\nelse if (plan.includes('PROFESSIONAL') || (body.fleet_size || 0) >= 50) tier = 'REGIONAL_3PL';\nelse if (plan.includes('BUSINESS') || (body.annual_shipments || 0) >= 10000) tier = 'ENTERPRISE_SHIPPER';\nconst compFlags = [];\nif (flags.includes('hazmat') || body.hazmat_certified) compFlags.push('HAZMAT_49CFR');\nif (flags.includes('customs_broker') || body.ctpat_member) compFlags.push('CBP_CTPAT');\nif (flags.includes('cold_chain')) compFlags.push('COLD_CHAIN_GDP');\nif (flags.includes('oversize') || body.oversize_carrier) compFlags.push('OVERSIZE_49CFR');\nif (flags.includes('iata_cargo')) compFlags.push('IATA_CASS');\nreturn [{json: {\n  customerId: body.customer_id || body.id,\n  companyName: body.company_name || body.name,\n  email: body.email, contactName: body.contact_name,\n  tier, compFlags, plan,\n  fleetSize: body.fleet_size || 0,\n  annualShipments: body.annual_shipments || 0,\n  onboardedAt: new Date().toISOString()\n}}];"
      },
      "position": [
        460,
        300
      ]
    },
    {
      "name": "Send Day 0 Welcome Email",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2,
      "parameters": {
        "operation": "send",
        "toList": "={{ $json.email }}",
        "subject": "Welcome to the platform \u2014 your FMCSA/CBP compliance quickstart",
        "message": "={{ 'Hi ' + $json.contactName + ',\\n\\nWelcome aboard. Your account tier: ' + $json.tier + '.\\n\\nCompliance flags detected: ' + ($json.compFlags.join(', ') || 'standard') + '.\\n\\nKey resources for you:\\n\u2022 ELD API documentation: [link]\\n\u2022 FMCSA HOS integration guide: [link]\\n' + ($json.compFlags.includes('HAZMAT_49CFR') ? '\u2022 49 CFR HMR hazmat data handling guide: [link]\\n' : '') + ($json.compFlags.includes('CBP_CTPAT') ? '\u2022 CBP AES/ISF integration checklist: [link]\\n' : '') + ($json.compFlags.includes('IATA_CASS') ? '\u2022 IATA CASS billing reconciliation guide: [link]\\n' : '') + '\\nYour dedicated onboarding specialist: [name]\\n\\nBest,\\nThe Team' }}"
      },
      "position": [
        680,
        300
      ]
    },
    {
      "name": "Log to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "parameters": {
        "operation": "append",
        "documentId": "YOUR_SHEET_ID",
        "sheetName": "onboarding_log",
        "columns": {
          "mappingMode": "autoMapInputData"
        }
      },
      "position": [
        680,
        460
      ]
    },
    {
      "name": "Wait 3 Days",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1,
      "parameters": {
        "resume": "timeInterval",
        "amount": 3,
        "unit": "days"
      },
      "position": [
        900,
        300
      ]
    },
    {
      "name": "Day 3 Integration Tips",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2,
      "parameters": {
        "operation": "send",
        "toList": "={{ $('Extract & Classify Customer').item.json.email }}",
        "subject": "Day 3: Top 3 integration patterns for {{ $('Extract & Classify Customer').item.json.tier }}",
        "message": "={{ 'Hi ' + $('Extract & Classify Customer').item.json.contactName + ',\\n\\nHere are the top integration patterns for ' + $('Extract & Classify Customer').item.json.tier + ' customers:\\n\\n1. Real-time ELD event webhooks to your TMS\\n2. Automated HOS violation alerts to dispatch\\n3. Driver DQ file expiry notifications\\n\\nBook a 30-min integration call: [link]\\n\\nBest,\\nThe Team' }}"
      },
      "position": [
        1120,
        300
      ]
    },
    {
      "name": "Wait 4 More Days",
      "type": "n8n-nodes-base.wait",
      "typeVersion": 1,
      "parameters": {
        "resume": "timeInterval",
        "amount": 4,
        "unit": "days"
      },
      "position": [
        1340,
        300
      ]
    },
    {
      "name": "Day 7 Feature Expansion",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2,
      "parameters": {
        "operation": "send",
        "toList": "={{ $('Extract & Classify Customer').item.json.email }}",
        "subject": "Week 1 complete \u2014 advanced compliance features you haven't tried yet",
        "message": "={{ 'Hi ' + $('Extract & Classify Customer').item.json.contactName + ',\\n\\nYou\\'re one week in. Here\\'s what customers at your tier typically unlock next:\\n\\n\u2022 Automated FMCSA pre-employment screening notifications\\n\u2022 CBP ISF 10+2 filing status webhooks\\n\u2022 Driver DQ file centralized expiry dashboard\\n\\nSchedule your Week 2 review: [link]\\n\\nBest,\\nThe Team' }}"
      },
      "position": [
        1560,
        300
      ]
    }
  ],
  "connections": {
    "Webhook Trigger": {
      "main": [
        [
          {
            "node": "Extract & Classify Customer",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Extract & Classify Customer": {
      "main": [
        [
          {
            "node": "Send Day 0 Welcome Email",
            "type": "main",
            "index": 0
          },
          {
            "node": "Log to Sheets",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Send Day 0 Welcome Email": {
      "main": [
        [
          {
            "node": "Wait 3 Days",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 3 Days": {
      "main": [
        [
          {
            "node": "Day 3 Integration Tips",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Day 3 Integration Tips": {
      "main": [
        [
          {
            "node": "Wait 4 More Days",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Wait 4 More Days": {
      "main": [
        [
          {
            "node": "Day 7 Feature Expansion",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Why self-host: Customer onboarding emails for HAZMAT carriers contain company DOT numbers, C-TPAT membership details, and fleet compliance flags. Routing these through Zapier puts third-party processors in your data chain — a problem for SOC2 CC6.7 and GDPR Art. 28.


Workflow 2: ELD/TMS API & Integration Health Monitor

Your platform's uptime is your customer's FMCSA compliance uptime. If your ELD API goes down during a driver's HOS window, that's a recordkeeping violation — and your customer will blame you.

Trigger: Schedule (every 5 minutes)

{
  "name": "ELD/TMS Integration Health Monitor",
  "nodes": [
    {
      "name": "Every 5 Minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1,
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 5
            }
          ]
        }
      },
      "position": [
        240,
        300
      ]
    },
    {
      "name": "Load Integration List",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "parameters": {
        "jsCode": "return [\n  {json: {customerId: 'cust_001', integration: 'ELD_API', endpoint: 'https://eld.yourplatform.com/health', type: 'FMCSA_ELD', sla_minutes: 2}},\n  {json: {customerId: 'cust_002', integration: 'TMS_WEBHOOK', endpoint: 'https://tms.yourplatform.com/ping', type: 'TMS_CORE', sla_minutes: 5}},\n  {json: {customerId: 'cust_003', integration: 'CUSTOMS_API', endpoint: 'https://customs.yourplatform.com/aes/health', type: 'CBP_AES', sla_minutes: 10}},\n  {json: {customerId: 'cust_004', integration: 'CASS_BILLING', endpoint: 'https://cass.yourplatform.com/health', type: 'IATA_CASS', sla_minutes: 15}}\n];"
      },
      "position": [
        460,
        300
      ]
    },
    {
      "name": "HTTP Ping Each Integration",
      "type": "n8n-nodes-base.httpRequest",
      "typeVersion": 4,
      "parameters": {
        "url": "={{ $json.endpoint }}",
        "method": "GET",
        "timeout": 8000,
        "continueOnFail": true
      },
      "position": [
        680,
        300
      ]
    },
    {
      "name": "Evaluate Status",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "parameters": {
        "jsCode": "const input = $input.first().json;\nconst prev = $input.first().json;\nconst statusCode = prev.statusCode || 0;\nconst integType = $('Load Integration List').item.json.type;\nlet status = 'OK';\nlet severity = null;\nlet complianceNote = '';\nif (statusCode === 0 || statusCode >= 500) {\n  status = 'DOWN';\n  severity = 'CRITICAL';\n  if (integType === 'FMCSA_ELD') complianceNote = 'FMCSA 49 CFR \u00a7395.8 recordkeeping risk \u2014 drivers cannot log HOS events';\n  else if (integType === 'CBP_AES') complianceNote = 'CBP AES pre-departure filing at risk \u2014 export holds possible under 15 CFR \u00a730.4';\n  else if (integType === 'IATA_CASS') complianceNote = 'IATA CASS settlement cycle at risk \u2014 billing reconciliation window affected';\n} else if (statusCode >= 400) {\n  status = 'AUTH_ERROR';\n  severity = 'HIGH';\n} else if (prev.responseTime > ($('Load Integration List').item.json.sla_minutes * 60 * 1000)) {\n  status = 'DEGRADED';\n  severity = 'WARNING';\n}\nreturn [{json: {\n  ...$('Load Integration List').item.json,\n  status, severity, complianceNote,\n  checkedAt: new Date().toISOString(),\n  responseTime: prev.responseTime || 0\n}}];"
      },
      "position": [
        900,
        300
      ]
    },
    {
      "name": "IF Critical",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "parameters": {
        "conditions": {
          "options": {
            "caseSensitive": false
          },
          "conditions": [
            {
              "leftValue": "={{ $json.severity }}",
              "rightValue": "CRITICAL",
              "operator": {
                "type": "string",
                "operation": "equals"
              }
            }
          ]
        }
      },
      "position": [
        1120,
        300
      ]
    },
    {
      "name": "Slack Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2,
      "parameters": {
        "channel": "#platform-incidents",
        "text": "={{ ':red_circle: CRITICAL \u2014 ' + $json.integration + ' DOWN\\nCustomer: ' + $json.customerId + '\\nType: ' + $json.type + '\\n' + ($json.complianceNote ? 'Compliance: ' + $json.complianceNote + '\\n' : '') + 'Checked: ' + $json.checkedAt }}"
      },
      "position": [
        1340,
        200
      ]
    }
  ],
  "connections": {
    "Every 5 Minutes": {
      "main": [
        [
          {
            "node": "Load Integration List",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Integration List": {
      "main": [
        [
          {
            "node": "HTTP Ping Each Integration",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "HTTP Ping Each Integration": {
      "main": [
        [
          {
            "node": "Evaluate Status",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Evaluate Status": {
      "main": [
        [
          {
            "node": "IF Critical",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Critical": {
      "main": [
        [
          {
            "node": "Slack Alert",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

FMCSA angle: Under 49 CFR §395.8, carriers must maintain ELD records for 6 months. If your ELD API is down and drivers can't log, the carrier faces violation. Your uptime SLA is their compliance SLA.


Workflow 3: FMCSA/CBP/IATA/FDA Supply Chain Compliance Deadline Tracker

LogisticsTech SaaS vendors face a dense compliance calendar. Missing a filing deadline doesn't just hurt your customer — it can trigger DOT audits of their fleet.

Trigger: Schedule (weekdays 8 AM)

{
  "name": "LogisticsTech Compliance Deadline Tracker",
  "nodes": [
    {
      "name": "Weekdays 8 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1,
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1-5"
            }
          ]
        }
      },
      "position": [
        240,
        300
      ]
    },
    {
      "name": "Load Compliance Deadlines",
      "type": "n8n-nodes-base.googleSheets",
      "typeVersion": 4,
      "parameters": {
        "operation": "readAllRows",
        "documentId": "YOUR_SHEET_ID",
        "sheetName": "compliance_deadlines"
      },
      "position": [
        460,
        300
      ]
    },
    {
      "name": "Score & Route Deadlines",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "parameters": {
        "jsCode": "const today = new Date();\nconst alerts = [];\nfor (const item of $input.all()) {\n  const d = item.json;\n  const due = new Date(d.due_date);\n  const days = Math.ceil((due - today) / 86400000);\n  if (d.alert_sent_date === today.toISOString().slice(0,10)) continue;\n  let urgency = null;\n  if (days < 0) urgency = 'OVERDUE';\n  else if (days <= 7) urgency = 'CRITICAL';\n  else if (days <= 21) urgency = 'URGENT';\n  else if (days <= 45) urgency = 'WARNING';\n  else if (days <= 90) urgency = 'NOTICE';\n  if (!urgency) continue;\n\n  const typeMap = {\n    'FMCSA_BIENNIAL_UPDATE': 'FMCSA MCS-150 biennial update (49 CFR \u00a7390.19)',\n    'FMCSA_DRUG_TESTING_ANNUAL': 'FMCSA DOT drug & alcohol testing program annual rate filing (49 CFR Part 382)',\n    'FMCSA_DRUG_TESTING_CLEARINGHOUSE': 'FMCSA Drug & Alcohol Clearinghouse annual query',\n    'DOT_HAZMAT_REGISTRATION': 'PHMSA hazmat shipper/carrier registration renewal (49 CFR \u00a7107.620)',\n    'CBP_CTPAT_ANNUAL_REVIEW': 'CBP C-TPAT annual security profile review',\n    'CBP_ISF_BOND_RENEWAL': 'CBP ISF continuous bond annual renewal',\n    'IATA_CASS_BILLING_RECONCILIATION': 'IATA CASS monthly billing reconciliation deadline',\n    'IATA_DGR_TRAINING_RECURRENT': 'IATA DGR dangerous goods recurrent training 24-month expiry',\n    'FDA_FSMA_204_TRACEABILITY': 'FDA FSMA \u00a7204 supply chain traceability records (Jan 2026 effective)',\n    'FMCSA_SAFETY_FITNESS_DETERMINATION': 'FMCSA safety fitness determination response deadline',\n    'EU_CSDDD_SUPPLY_CHAIN_DUE_DILIGENCE': 'EU Corporate Sustainability Due Diligence Directive (CSDDD) supply chain audit',\n    'GERMAN_LKSG_ANNUAL_REPORT': 'German Supply Chain Due Diligence Act (LkSG) annual risk analysis report'\n  };\n\n  alerts.push({json: {\n    ...d, days, urgency,\n    deadlineLabel: typeMap[d.deadline_type] || d.deadline_type,\n    formattedDue: due.toISOString().slice(0,10)\n  }});\n}\nreturn alerts.length ? alerts : [{json: {noAlerts: true}}];"
      },
      "position": [
        680,
        300
      ]
    },
    {
      "name": "IF Has Alerts",
      "type": "n8n-nodes-base.if",
      "typeVersion": 2,
      "parameters": {
        "conditions": {
          "conditions": [
            {
              "leftValue": "={{ $json.noAlerts }}",
              "rightValue": true,
              "operator": {
                "type": "boolean",
                "operation": "notEqual"
              }
            }
          ]
        }
      },
      "position": [
        900,
        300
      ]
    },
    {
      "name": "Slack Compliance Alert",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2,
      "parameters": {
        "channel": "#compliance-ops",
        "text": "={{ ($json.urgency === 'OVERDUE' ? ':rotating_light:' : $json.urgency === 'CRITICAL' ? ':red_circle:' : $json.urgency === 'URGENT' ? ':large_orange_circle:' : ':large_yellow_circle:') + ' ' + $json.urgency + ' \u2014 ' + $json.deadlineLabel + '\\nDue: ' + $json.formattedDue + ' (' + $json.days + ' days)\\nOwner: ' + ($json.owner || 'unassigned') }}"
      },
      "position": [
        1120,
        200
      ]
    }
  ],
  "connections": {
    "Weekdays 8 AM": {
      "main": [
        [
          {
            "node": "Load Compliance Deadlines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Load Compliance Deadlines": {
      "main": [
        [
          {
            "node": "Score & Route Deadlines",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Score & Route Deadlines": {
      "main": [
        [
          {
            "node": "IF Has Alerts",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "IF Has Alerts": {
      "main": [
        [
          {
            "node": "Slack Compliance Alert",
            "type": "main",
            "index": 0
          }
        ],
        []
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

12 deadline types covered: FMCSA biennial MCS-150 update, DOT drug & alcohol clearinghouse annual query, PHMSA hazmat registration renewal, CBP C-TPAT annual review, CBP ISF continuous bond renewal, IATA CASS monthly billing reconciliation, IATA DGR recurrent training (24-month), FDA FSMA §204 traceability, FMCSA safety fitness determination, EU CSDDD supply chain due diligence, German LkSG annual risk analysis — and FMCSA drug testing annual rate filing.


Workflow 4: Shipment Delay & Compliance Exception Pipeline

When a shipment gets flagged — by CBP, a broken cold chain sensor, or a HAZMAT incident — your platform needs to route that event in seconds, not minutes.

Trigger: Webhook (compliance event from your TMS/ELD)

{
  "name": "Shipment Compliance Exception Pipeline",
  "nodes": [
    {
      "name": "Compliance Event Webhook",
      "type": "n8n-nodes-base.webhook",
      "typeVersion": 1,
      "parameters": {
        "httpMethod": "POST",
        "path": "logistics-compliance-event"
      },
      "position": [
        240,
        300
      ]
    },
    {
      "name": "Map Event Severity",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "parameters": {
        "jsCode": "const body = $input.first().json.body || $input.first().json;\nconst severityMap = {\n  'HOS_VIOLATION': {sev: 'CRITICAL', reg: 'FMCSA 49 CFR \u00a7395.3', action: 'Driver must go off-duty immediately. Log event in ELD system.'},\n  'HAZMAT_INCIDENT': {sev: 'CRITICAL', reg: '49 CFR \u00a7171.15 (PHMSA)', action: 'Immediate PHMSA telephonic report required within 30 minutes if release occurred.'},\n  'CUSTOMS_HOLD': {sev: 'HIGH', reg: 'CBP 19 USC \u00a71499', action: 'CBP examination hold. Notify customs broker and await exam assignment.'},\n  'COLD_CHAIN_BREACH': {sev: 'HIGH', reg: 'FDA GDP / FSMA \u00a7204', action: 'Quarantine shipment. Temperature excursion log required for FDA traceability records.'},\n  'OVERSIZE_PERMIT_EXPIRED': {sev: 'HIGH', reg: '49 CFR \u00a7392.9 + state DOT', action: 'Load must be held. Contact state DOT permitting office for emergency extension.'},\n  'ISF_FILING_LATE': {sev: 'HIGH', reg: 'CBP 19 CFR \u00a7149.2 (10+2)', action: 'ISF \u00a75,000/violation penalty risk. File immediately via ABI or Simplified Entry.'},\n  'DRIVER_DISQUALIFICATION': {sev: 'HIGH', reg: 'FMCSA 49 CFR \u00a7391.15', action: 'Driver DQ flag. Remove from dispatch queue pending review.'},\n  'WEIGHT_LIMIT_VIOLATION': {sev: 'MEDIUM', reg: '23 USC \u00a7127 / state bridge laws', action: 'Re-route or obtain overweight permit before crossing state line.'},\n  'CASS_BILLING_DISPUTE': {sev: 'MEDIUM', reg: 'IATA CASS Manual \u00a73', action: 'Raise CASS dispute within 90-day resolution window.'}\n};\nconst evType = (body.event_type || '').toUpperCase();\nconst mapped = severityMap[evType] || {sev: 'LOW', reg: 'Unknown', action: 'Review manually'};\nreturn [{json: {\n  ...body,\n  eventType: evType,\n  severity: mapped.sev,\n  regulation: mapped.reg,\n  requiredAction: mapped.action,\n  shipmentId: body.shipment_id || body.id,\n  driverId: body.driver_id,\n  customerId: body.customer_id,\n  receivedAt: new Date().toISOString()\n}}];"
      },
      "position": [
        460,
        300
      ]
    },
    {
      "name": "Route by Severity",
      "type": "n8n-nodes-base.switch",
      "typeVersion": 3,
      "parameters": {
        "mode": "rules",
        "rules": {
          "values": [
            {
              "conditions": {
                "conditions": [
                  {
                    "leftValue": "={{ $json.severity }}",
                    "rightValue": "CRITICAL",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "critical"
            },
            {
              "conditions": {
                "conditions": [
                  {
                    "leftValue": "={{ $json.severity }}",
                    "rightValue": "HIGH",
                    "operator": {
                      "type": "string",
                      "operation": "equals"
                    }
                  }
                ]
              },
              "renameOutput": true,
              "outputKey": "high"
            }
          ]
        }
      },
      "position": [
        680,
        300
      ]
    },
    {
      "name": "Slack CRITICAL",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2,
      "parameters": {
        "channel": "#incidents-critical",
        "text": "={{ ':rotating_light: CRITICAL COMPLIANCE EVENT\\nType: ' + $json.eventType + '\\nRegulation: ' + $json.regulation + '\\nShipment: ' + $json.shipmentId + '\\nRequired Action: ' + $json.requiredAction + '\\nReceived: ' + $json.receivedAt }}"
      },
      "position": [
        900,
        160
      ]
    },
    {
      "name": "Slack HIGH",
      "type": "n8n-nodes-base.slack",
      "typeVersion": 2,
      "parameters": {
        "channel": "#incidents-high",
        "text": "={{ ':large_orange_circle: HIGH SEVERITY EVENT\\nType: ' + $json.eventType + '\\nRegulation: ' + $json.regulation + '\\nShipment: ' + $json.shipmentId + '\\nRequired Action: ' + $json.requiredAction }}"
      },
      "position": [
        900,
        380
      ]
    },
    {
      "name": "Log to Postgres",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "parameters": {
        "operation": "insert",
        "schema": "public",
        "table": "compliance_incidents",
        "columns": "shipment_id,customer_id,driver_id,event_type,severity,regulation,received_at"
      },
      "position": [
        1120,
        300
      ]
    }
  ],
  "connections": {
    "Compliance Event Webhook": {
      "main": [
        [
          {
            "node": "Map Event Severity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Map Event Severity": {
      "main": [
        [
          {
            "node": "Route by Severity",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Route by Severity": {
      "main": [
        [
          {
            "node": "Slack CRITICAL",
            "type": "main",
            "index": 0
          }
        ],
        [
          {
            "node": "Slack HIGH",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack CRITICAL": {
      "main": [
        [
          {
            "node": "Log to Postgres",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Slack HIGH": {
      "main": [
        [
          {
            "node": "Log to Postgres",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

9 event types with regulatory citations: HOS violation (§395.3), HAZMAT incident (§171.15 30-min telephonic report), CBP customs hold (19 USC §1499), cold chain breach (FSMA §204), oversize permit expired (§392.9), ISF late filing (19 CFR §149.2 10+2 rule), driver disqualification (§391.15), weight limit violation (23 USC §127), IATA CASS billing dispute.


Workflow 5: Weekly LogisticsTech Platform KPI Dashboard

Your CEO wants to know MRR. Your Head of Compliance wants to know incident rate. This report does both.

Trigger: Schedule (Monday 8 AM)

{
  "name": "Weekly LogisticsTech Platform KPI Dashboard",
  "nodes": [
    {
      "name": "Monday 8 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "typeVersion": 1,
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1"
            }
          ]
        }
      },
      "position": [
        240,
        300
      ]
    },
    {
      "name": "Query Platform Metrics",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT COUNT(*) as total_customers, SUM(mrr_usd) as mrr, COUNT(CASE WHEN tier='MEGA_BROKER' THEN 1 END) as mega_brokers, COUNT(CASE WHEN tier='REGIONAL_3PL' THEN 1 END) as regional_3pl FROM customers WHERE status='active'"
      },
      "position": [
        460,
        200
      ]
    },
    {
      "name": "Query Compliance Incidents",
      "type": "n8n-nodes-base.postgres",
      "typeVersion": 2,
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT COUNT(*) as total_incidents, COUNT(CASE WHEN severity='CRITICAL' THEN 1 END) as critical, COUNT(CASE WHEN event_type='HOS_VIOLATION' THEN 1 END) as hos_violations, COUNT(CASE WHEN event_type='HAZMAT_INCIDENT' THEN 1 END) as hazmat_incidents, COUNT(CASE WHEN event_type='CUSTOMS_HOLD' THEN 1 END) as customs_holds FROM compliance_incidents WHERE received_at >= NOW() - INTERVAL '7 days'"
      },
      "position": [
        460,
        440
      ]
    },
    {
      "name": "Build KPI Report",
      "type": "n8n-nodes-base.code",
      "typeVersion": 1,
      "parameters": {
        "jsCode": "const metrics = $('Query Platform Metrics').first().json;\nconst incidents = $('Query Compliance Incidents').first().json;\nconst weekStr = new Date().toISOString().slice(0,10);\nconst hosFlag = incidents.hos_violations > 5 ? ' \u26a0\ufe0f HOS VIOLATION SPIKE' : '';\nconst hazmatFlag = incidents.hazmat_incidents > 0 ? ' \ud83d\udea8 HAZMAT INCIDENT(S)' : '';\nconst html = `<h2>LogisticsTech Platform KPI \u2014 Week of ${weekStr}</h2>\n<h3>Revenue</h3>\n<p>MRR: $${Number(metrics.mrr||0).toLocaleString()} | Active customers: ${metrics.total_customers}</p>\n<p>Mega brokers: ${metrics.mega_brokers} | Regional 3PLs: ${metrics.regional_3pl}</p>\n<h3>Compliance Incidents (Last 7 Days)</h3>\n<p>Total: ${incidents.total_incidents} | Critical: ${incidents.critical}${hosFlag}${hazmatFlag}</p>\n<p>HOS violations: ${incidents.hos_violations} | HAZMAT incidents: ${incidents.hazmat_incidents} | Customs holds: ${incidents.customs_holds}</p>\n<hr><p>Platform KPI report \u2014 confidential</p>`;\nreturn [{json: {html, weekStr, hosFlag, hazmatFlag}}];"
      },
      "position": [
        680,
        300
      ]
    },
    {
      "name": "Email CEO + CISO",
      "type": "n8n-nodes-base.gmail",
      "typeVersion": 2,
      "parameters": {
        "operation": "send",
        "toList": "ceo@yourcompany.com",
        "ccList": "ciso@yourcompany.com",
        "subject": "={{ 'Weekly Platform KPI \u2014 ' + $json.weekStr + ($json.hosFlag || $json.hazmatFlag ? ' ACTION REQUIRED' : '') }}",
        "message": "={{ $json.html }}",
        "options": {
          "appendAttribution": false
        }
      },
      "position": [
        900,
        300
      ]
    }
  ],
  "connections": {
    "Monday 8 AM": {
      "main": [
        [
          {
            "node": "Query Platform Metrics",
            "type": "main",
            "index": 0
          },
          {
            "node": "Query Compliance Incidents",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query Platform Metrics": {
      "main": [
        [
          {
            "node": "Build KPI Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Query Compliance Incidents": {
      "main": [
        [
          {
            "node": "Build KPI Report",
            "type": "main",
            "index": 0
          }
        ]
      ]
    },
    "Build KPI Report": {
      "main": [
        [
          {
            "node": "Email CEO + CISO",
            "type": "main",
            "index": 0
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

CISO BCC is intentional: LogisticsTech SaaS platforms handle HAZMAT manifests, driver PII, and customs filing data. The CISO needs to know when compliance incident rates spike — that's a SOC2 CC7.2 operations monitoring obligation.


n8n vs Zapier/Make for LogisticsTech

Factor n8n (self-hosted) Zapier / Make
ELD data sovereignty Stays in your VPC Third-party server
HAZMAT incident records Git-versioned audit trail No audit trail
CBP AES filing data In-enclave External cloud
FMCSA HOS timing logic Custom code nodes Limited conditional logic
IATA CASS reconciliation Full data access API rate limits
FDA FSMA §204 traceability Postgres-backed audit log Not purpose-built
Cost at 100K events/month ~$50/month hosting $200–$400+/month

Get the complete workflow pack

All 5 workflows above are available as import-ready JSON in the FlowKit n8n Automation Templates pack:

stripeai.gumroad.com — individual templates from $12 | complete bundle $97

LogisticsTech teams: the compliance deadline tracker and incident pipeline are particularly useful if you're tracking FMCSA filings, CBP bond renewals, or IATA CASS billing cycles alongside your regular engineering sprint calendar.


Have a LogisticsTech compliance workflow you'd like to see? Drop it in the comments.

Top comments (0)