Insurance is one of the most regulated industries on earth. Every US state has its own Department of Insurance (DOI) with different market conduct rules, claims handling standards, rate filing requirements, and annual reporting deadlines. Multiply that by HIPAA for health insurers, SOX for publicly traded carriers, NAIC model regulations, Lloyd's market rules, and GDPR for EU policyholder data — and you have hundreds of compliance events per year.
The problem with Zapier: 30-day log retention. State DOI market conduct exams can look back 3–5 years. HIPAA requires audit trails for PHI access decisions. SOX Section 302 requires CEO/CFO certification that IT controls are adequate — and an automation platform with 30-day logs is a control weakness.
n8n fixes this: self-hosted on your VPC, full execution logs to Postgres, unlimited retention, no per-task billing at 100K+ automation runs per day.
Here are 5 complete automations InsurTech SaaS vendors can deploy today.
Workflow 1: InsurTech Customer Regulatory Onboarding Drip
{
"nodes": [
{
"id": "1",
"name": "Customer Signed Up",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
300
],
"parameters": {
"path": "insurtech-onboard",
"responseMode": "responseNode",
"options": {}
}
},
{
"id": "2",
"name": "Classify Tier and Flags",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
460,
300
],
"parameters": {
"jsCode": "const c = $json; const gwp = c.gwp_annual_usd || 0; let tier; if (gwp >= 5e9) tier = 'LARGE_CARRIER'; else if (gwp >= 5e8) tier = 'MID_MARKET_CARRIER'; else if (gwp > 0) tier = 'REGIONAL_CARRIER'; else if (c.company_type === 'mga') tier = 'MGA_MGU'; else tier = 'INSURTECH_STARTUP'; const flags = []; if (c.handles_phi) flags.push('HIPAA_REQUIRED'); if (c.publicly_traded) flags.push('SOX_REPORTING'); if (gwp > 0) flags.push('NAIC_RBC_APPLICABLE'); if (c.eu_operations) flags.push('GDPR_APPLICABLE'); if (c.ca_policyholders) flags.push('CCPA_REQUIRED'); if (c.lloyds_market) flags.push('LLOYDS_MARKET_APPLICABLE'); if ((c.state_count || 1) > 1) flags.push('STATE_DOI_FILING_REQUIRED'); if (c.uses_credit_scoring) flags.push('FCRA_APPLICABLE'); return [{ json: { ...c, tier, compliance_flags: flags } }];"
}
},
{
"id": "3",
"name": "Day 0 Welcome Email",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
680,
300
],
"parameters": {
"operation": "send",
"toList": "={{ $json.email }}",
"subject": "Welcome to {{ $json.platform_name }} \u2014 Your Compliance Onboarding Guide",
"message": "Hi {{ $json.first_name }},\\n\\nWelcome aboard. Your account is configured for {{ $json.tier }}.\\n\\n{{ $json.compliance_flags.includes('HIPAA_REQUIRED') ? 'HIPAA note: your Business Associate Agreement is attached. PHI stays inside your VPC \u2014 review the data routing guide linked below.' : '' }}\\n{{ $json.compliance_flags.includes('SOX_REPORTING') ? 'SOX \u00a7302: your audit trail is logging to Postgres. IT control documentation attached.' : '' }}\\n{{ $json.compliance_flags.includes('NAIC_RBC_APPLICABLE') ? 'NAIC RBC: annual statement due March 1 \u2014 we have pre-built deadline tracking for this.' : '' }}\\n\\nBest,\\nThe {{ $json.platform_name }} Team"
}
},
{
"id": "4",
"name": "Wait 3 Days",
"type": "n8n-nodes-base.wait",
"typeVersion": 1,
"position": [
900,
300
],
"parameters": {
"amount": 3,
"unit": "days"
}
},
{
"id": "5",
"name": "Day 3 Compliance Checklist",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
1120,
300
],
"parameters": {
"operation": "send",
"toList": "={{ $json.email }}",
"subject": "Your DOI Compliance Checklist \u2014 Day 3",
"message": "Hi {{ $json.first_name }},\\n\\nDay 3 checklist:\\n\\n{{ $json.compliance_flags.includes('NAIC_RBC_APPLICABLE') ? '\u2713 NAIC RBC filing March 1 \u2014 add to compliance calendar.' : '' }}\\n{{ $json.compliance_flags.includes('STATE_DOI_FILING_REQUIRED') ? '\u2713 Multi-state DOI annual reports \u2014 configure deadline tracker for each state.' : '' }}\\n{{ $json.compliance_flags.includes('GDPR_APPLICABLE') ? '\u2713 GDPR DPIA: schedule annual review. Art.28 DPA required for all subprocessors.' : '' }}\\n{{ $json.compliance_flags.includes('LLOYDS_MARKET_APPLICABLE') ? \"\u2713 Lloyd's Business Plan submission due October 1 \u2014 add to calendar now.\" : '' }}\\n\\nReply with questions.\\n\\nBest,\\nThe {{ $json.platform_name }} Team"
}
},
{
"id": "6",
"name": "Wait 4 Days",
"type": "n8n-nodes-base.wait",
"typeVersion": 1,
"position": [
1340,
300
],
"parameters": {
"amount": 4,
"unit": "days"
}
},
{
"id": "7",
"name": "Day 7 Account Health Check",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
1560,
300
],
"parameters": {
"operation": "send",
"toList": "={{ $json.email }}",
"subject": "Week 1 Complete \u2014 Your {{ $json.tier }} Compliance Dashboard",
"message": "Hi {{ $json.first_name }},\\n\\nWeek 1 done. Your compliance calendar is active, audit trail is logging, and DOI deadline tracker is live.\\n\\n{{ $json.compliance_flags.includes('SOX_REPORTING') ? 'SOX note: quarterly certification reminders are set for 40 days after each quarter end. CFO will be auto-briefed on any control exceptions.' : '' }}\\n\\nBook a 30-min compliance review: [Calendly link]\\n\\nBest,\\nThe {{ $json.platform_name }} Team"
}
}
],
"connections": {
"Customer Signed Up": {
"main": [
[
{
"node": "Classify Tier and Flags",
"type": "main",
"index": 0
}
]
]
},
"Classify Tier and Flags": {
"main": [
[
{
"node": "Day 0 Welcome Email",
"type": "main",
"index": 0
}
]
]
},
"Day 0 Welcome Email": {
"main": [
[
{
"node": "Wait 3 Days",
"type": "main",
"index": 0
}
]
]
},
"Wait 3 Days": {
"main": [
[
{
"node": "Day 3 Compliance Checklist",
"type": "main",
"index": 0
}
]
]
},
"Day 3 Compliance Checklist": {
"main": [
[
{
"node": "Wait 4 Days",
"type": "main",
"index": 0
}
]
]
},
"Wait 4 Days": {
"main": [
[
{
"node": "Day 7 Account Health Check",
"type": "main",
"index": 0
}
]
]
}
}
}
What it does: Classifies new customers by carrier tier and compliance obligations, then runs a 3-touch email sequence (Day 0 / Day 3 / Day 7) that adapts content per flag.
Carrier tiers:
-
LARGE_CARRIER— GWP > $5B -
MID_MARKET_CARRIER— GWP $500M–$5B -
REGIONAL_CARRIER— GWP < $500M -
MGA_MGU— managing general agents and underwriters -
INSURTECH_STARTUP— new entrant, no GWP history
Compliance flags set at sign-up:
-
HIPAA_REQUIRED— health insurance carriers handling PHI -
SOX_REPORTING— publicly traded carriers (Section 302/906) -
NAIC_RBC_APPLICABLE— carriers subject to NAIC Risk-Based Capital requirements -
GDPR_APPLICABLE— EU operations or EU policyholder data -
CCPA_REQUIRED— California policyholders (CPRA data inventory required) -
LLOYDS_MARKET_APPLICABLE— Lloyd's syndicates and coverholders -
STATE_DOI_FILING_REQUIRED— multi-state filers with different annual report deadlines -
FCRA_APPLICABLE— carriers using credit-based insurance scoring
Day 3 email for HIPAA-flagged accounts explains PHI routing compliance. Day 7 for SOX accounts covers quarterly certification prep.
Workflow 2: Claims Processing & SLA Breach Monitor
{
"nodes": [
{
"id": "1",
"name": "Every 5 Minutes",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 5
}
]
}
}
},
{
"id": "2",
"name": "Fetch Open Claims",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.2,
"position": [
460,
300
],
"parameters": {
"url": "https://api.yourplatform.com/v1/claims?status=open&limit=500",
"authentication": "predefinedCredentialType",
"nodeCredentialType": "httpBearerAuth",
"options": {}
}
},
{
"id": "3",
"name": "Check SLA by State",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
300
],
"parameters": {
"jsCode": "const sla = { CA:{ack:15,decision:40,pay:30}, NY:{ack:15,decision:30,pay:30}, TX:{ack:15,decision:45,pay:5}, FL:{ack:14,decision:45,pay:20}, IL:{ack:15,decision:45,pay:30}, PA:{ack:15,decision:45,pay:15} }; const now=Date.now(); const breaches=[]; for(const claim of $input.all().map(i=>i.json)){ const s=sla[claim.state]||{ack:15,decision:45,pay:30}; const d=Math.floor((now-new Date(claim.opened_at))/86400000); if(!claim.acknowledged_at&&d>s.ack) breaches.push({...claim,breach:'ACKNOWLEDGE_SLA',sla_days:s.ack,days_overdue:d-s.ack}); else if(claim.acknowledged_at&&!claim.decision_at&&d>s.decision) breaches.push({...claim,breach:'DECISION_SLA',sla_days:s.decision,days_overdue:d-s.decision}); } return breaches.map(b=>({json:b}));"
}
},
{
"id": "4",
"name": "Any Breaches?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
900,
300
],
"parameters": {
"conditions": {
"options": {
"caseSensitive": true
},
"conditions": [
{
"id": "c1",
"leftValue": "={{ $input.all().length }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "gt"
}
}
]
}
}
},
{
"id": "5",
"name": "Alert Claims Ops",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
1120,
200
],
"parameters": {
"operation": "message",
"channel": "#claims-ops",
"text": "={{ `CLAIMS SLA BREACH\\nPolicy: ${$json.policy_number} | Carrier: ${$json.carrier_name}\\nState: ${$json.state} | Breach: ${$json.breach}\\nSLA: ${$json.sla_days}d | Days overdue: ${$json.days_overdue}\\nDOI audit trail: logged to Postgres.` }}"
}
},
{
"id": "6",
"name": "Log to Postgres",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
1340,
200
],
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO claims_sla_breaches (claim_id, policy_number, carrier, state, breach_type, days_overdue, detected_at) VALUES ('{{ $json.claim_id }}', '{{ $json.policy_number }}', '{{ $json.carrier_name }}', '{{ $json.state }}', '{{ $json.breach }}', {{ $json.days_overdue }}, NOW()) ON CONFLICT (claim_id, breach_type) DO UPDATE SET days_overdue=EXCLUDED.days_overdue, detected_at=NOW()"
}
}
],
"connections": {
"Every 5 Minutes": {
"main": [
[
{
"node": "Fetch Open Claims",
"type": "main",
"index": 0
}
]
]
},
"Fetch Open Claims": {
"main": [
[
{
"node": "Check SLA by State",
"type": "main",
"index": 0
}
]
]
},
"Check SLA by State": {
"main": [
[
{
"node": "Any Breaches?",
"type": "main",
"index": 0
}
]
]
},
"Any Breaches?": {
"main": [
[
{
"node": "Alert Claims Ops",
"type": "main",
"index": 0
}
],
[]
]
},
"Alert Claims Ops": {
"main": [
[
{
"node": "Log to Postgres",
"type": "main",
"index": 0
}
]
]
}
}
}
What it does: Polls your claims API every 5 minutes. Detects SLA breaches before a state DOI market conduct exam finds them first.
State claims SLA requirements (selected):
| State | Acknowledge | Decision | Pay After Decision |
|---|---|---|---|
| CA | 15 days | 40 days | 30 days |
| NY | 15 days | 30 days | 30 days |
| TX | 15 days | 45 days | 5 days |
| FL | 14 days | 45 days | 20 days |
| IL | 15 days | 45 days | 30 days |
On breach: Slack alert to #claims-ops with policy number, carrier, state code, and days overdue. Immutable Postgres log for DOI audit trail.
DOI angle: Market conduct exams routinely request claims handling data going back 3–5 years. Zapier's 30-day retention means your automation audit trail vanishes before the exam opens.
Workflow 3: DOI / NAIC / SOX / HIPAA Compliance Deadline Tracker
{
"nodes": [
{
"id": "1",
"name": "Weekdays 8 AM",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1-5"
}
]
}
}
},
{
"id": "2",
"name": "Read Compliance Calendar",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4.5,
"position": [
460,
300
],
"parameters": {
"operation": "readRows",
"documentId": {
"__rl": true,
"value": "YOUR_SHEET_ID",
"mode": "id"
},
"sheetName": {
"__rl": true,
"value": "Deadlines",
"mode": "name"
}
}
},
{
"id": "3",
"name": "Calculate Days Remaining",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
680,
300
],
"parameters": {
"jsCode": "const today=new Date(); const results=[]; for(const item of $input.all().map(i=>i.json)){ if(!item.deadline_date||!item.account_name) continue; const dl=new Date(item.deadline_date); const d=Math.floor((dl-today)/86400000); if(d>30) continue; const urgency=d<=7?'CRITICAL':d<=14?'HIGH':'MEDIUM'; results.push({json:{...item,days_left:d,urgency}}); } return results;"
}
},
{
"id": "4",
"name": "Has Deadlines?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
900,
300
],
"parameters": {
"conditions": {
"conditions": [
{
"id": "c1",
"leftValue": "={{ $input.all().length }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "gt"
}
}
]
}
}
},
{
"id": "5",
"name": "Slack Alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
1120,
200
],
"parameters": {
"operation": "message",
"channel": "#compliance-ops",
"text": "={{ `${$json.urgency==='CRITICAL'?'CRITICAL':'HIGH'} DEADLINE \u2014 ${$json.deadline_type}\\nAccount: ${$json.account_name} | Owner: ${$json.owner_email}\\nDue: ${$json.deadline_date} (${$json.days_left}d remaining)\\nRegulation: ${$json.regulation_ref||'see calendar'}` }}"
}
}
],
"connections": {
"Weekdays 8 AM": {
"main": [
[
{
"node": "Read Compliance Calendar",
"type": "main",
"index": 0
}
]
]
},
"Read Compliance Calendar": {
"main": [
[
{
"node": "Calculate Days Remaining",
"type": "main",
"index": 0
}
]
]
},
"Calculate Days Remaining": {
"main": [
[
{
"node": "Has Deadlines?",
"type": "main",
"index": 0
}
]
]
},
"Has Deadlines?": {
"main": [
[
{
"node": "Slack Alert",
"type": "main",
"index": 0
}
],
[]
]
}
}
}
What it does: Reads your compliance calendar from Google Sheets every weekday at 8 AM. Calculates days remaining for 12 deadline types. Sends tiered Slack alerts: CRITICAL (< 7 days) / HIGH (< 14 days) / MEDIUM (< 30 days).
Deadline types tracked:
-
STATE_DOI_ANNUAL_REPORT— varies by state, most March/April -
NAIC_RBC_FILING— March 1 annually (Risk-Based Capital report) -
NAIC_ANNUAL_STATEMENT— March 1 (Life / P&C / Health) -
SOX_QUARTERLY_CERTIFICATION— 45 days after each quarter end -
HIPAA_ANNUAL_RISK_ASSESSMENT— required under §164.308(a)(1) -
GDPR_DPIA_REVIEW— annual review for high-risk processing activities -
STATE_RATE_FILING— prior approval states require 30–60 day advance filing -
STATE_FORM_FILING— new policy forms require DOI approval in most states -
ACTUARY_ATTESTATION— appointed actuary annual opinion -
REINSURANCE_CONTRACT_RENEWAL— 60-day advance notice typically required -
LLOYDS_SYNDICATE_AUDIT— Lloyd's Business Plan submission (October 1) -
CCPA_ANNUAL_DATA_INVENTORY— CPRA requires annual data inventory update
50 US states × different DOI filing deadlines × multiple product lines = hundreds of compliance events per year that no simple scheduler can track reliably.
Workflow 4: Policy Incident & Regulatory Violation Alert Pipeline
{
"nodes": [
{
"id": "1",
"name": "Incident Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
240,
300
],
"parameters": {
"path": "insurtech-incident",
"responseMode": "responseNode",
"options": {}
}
},
{
"id": "2",
"name": "Dedup Check",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
460,
300
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT id FROM insurtech_incidents WHERE incident_type='{{ $json.incident_type }}' AND account_id='{{ $json.account_id }}' AND created_at > NOW()-INTERVAL '30 minutes'"
}
},
{
"id": "3",
"name": "New Incident?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
680,
300
],
"parameters": {
"conditions": {
"conditions": [
{
"id": "c1",
"leftValue": "={{ $('Dedup Check').all().length }}",
"rightValue": 0,
"operator": {
"type": "number",
"operation": "equals"
}
}
]
}
}
},
{
"id": "4",
"name": "Log Incident",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
900,
200
],
"parameters": {
"operation": "executeQuery",
"query": "INSERT INTO insurtech_incidents (account_id, account_name, incident_type, severity, details, created_at) VALUES ('{{ $json.account_id }}', '{{ $json.account_name }}', '{{ $json.incident_type }}', '{{ $json.severity }}', '{{ $json.details }}', NOW())"
}
},
{
"id": "5",
"name": "Route by Incident Type",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
1120,
200
],
"parameters": {
"mode": "rules",
"rules": {
"values": [
{
"outputKey": "doi_exam",
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"rightValue": "DOI_MARKET_CONDUCT_EXAM_NOTICE",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
}
},
{
"outputKey": "phi_breach",
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"rightValue": "DATA_BREACH_PHI",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
}
},
{
"outputKey": "sox_failure",
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"rightValue": "SOX_INTERNAL_CONTROL_FAILURE",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
}
},
{
"outputKey": "claims_violation",
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.incident_type }}",
"rightValue": "CLAIMS_HANDLING_VIOLATION",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
}
}
]
}
}
},
{
"id": "6",
"name": "Alert doi-exams",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
1340,
80
],
"parameters": {
"operation": "message",
"channel": "#doi-exams",
"text": "={{ `CRITICAL: DOI MARKET CONDUCT EXAM NOTICE\\nAccount: ${$json.account_name} | State: ${$json.state}\\nExam scope: ${$json.exam_scope||'claims handling'}\\nResponse deadline: ${$json.response_deadline}\\nAction: assign response team within 2h. Audit log ready in Postgres.` }}"
}
},
{
"id": "7",
"name": "Alert security-privacy",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
1340,
200
],
"parameters": {
"operation": "message",
"channel": "#security-privacy",
"text": "={{ `CRITICAL: PHI DATA BREACH\\nAccount: ${$json.account_name}\\nPHI records affected: ${$json.records_affected||'unknown'}\\nHIPAA 164.402: breach notification required within 60 days.\\nState breach laws may require shorter window.\\n60-day clock starts now.` }}"
}
},
{
"id": "8",
"name": "Alert sox-controls",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
1340,
320
],
"parameters": {
"operation": "message",
"channel": "#sox-controls",
"text": "={{ `CRITICAL: SOX INTERNAL CONTROL FAILURE\\nAccount: ${$json.account_name}\\nControl: ${$json.control_id}\\nFailure: ${$json.failure_description}\\nSOX 302: CFO must be briefed before next quarterly certification.` }}"
}
},
{
"id": "9",
"name": "Alert claims-compliance",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
1340,
440
],
"parameters": {
"operation": "message",
"channel": "#claims-compliance",
"text": "={{ `CRITICAL: CLAIMS HANDLING VIOLATION\\nAccount: ${$json.account_name} | State: ${$json.state}\\nViolation: ${$json.violation_description}\\nState DOI market conduct rules. Potential market conduct exam trigger.\\nDocument remediation steps now.` }}"
}
}
],
"connections": {
"Incident Webhook": {
"main": [
[
{
"node": "Dedup Check",
"type": "main",
"index": 0
}
]
]
},
"Dedup Check": {
"main": [
[
{
"node": "New Incident?",
"type": "main",
"index": 0
}
]
]
},
"New Incident?": {
"main": [
[
{
"node": "Log Incident",
"type": "main",
"index": 0
}
],
[]
]
},
"Log Incident": {
"main": [
[
{
"node": "Route by Incident Type",
"type": "main",
"index": 0
}
]
]
},
"Route by Incident Type": {
"doi_exam": [
[
{
"node": "Alert doi-exams",
"type": "main",
"index": 0
}
]
],
"phi_breach": [
[
{
"node": "Alert security-privacy",
"type": "main",
"index": 0
}
]
],
"sox_failure": [
[
{
"node": "Alert sox-controls",
"type": "main",
"index": 0
}
]
],
"claims_violation": [
[
{
"node": "Alert claims-compliance",
"type": "main",
"index": 0
}
]
]
}
}
}
What it does: Webhook receives incident events from your platform. Routes to the appropriate Slack channel based on type. 30-minute dedup prevents duplicate alerts. Immutable Postgres log.
7 incident types handled:
| Type | Severity | Response SLA | Regulation |
|---|---|---|---|
CLAIMS_HANDLING_VIOLATION |
CRITICAL | 1h | State DOI market conduct rules |
DOI_MARKET_CONDUCT_EXAM_NOTICE |
CRITICAL | 2h | State insurance code |
DATA_BREACH_PHI |
CRITICAL | 1h | HIPAA §164.402 / state breach laws |
NAIC_COMPLAINT_FILING |
HIGH | 4h | NAIC Complaint Database reporting |
SOX_INTERNAL_CONTROL_FAILURE |
CRITICAL | 2h | SOX §302 / §906 |
REINSURANCE_COUNTERPARTY_DOWNGRADE |
HIGH | 4h | NAIC RBC / AM Best rating impact |
LLOYDS_CAPACITY_WARNING |
CRITICAL | 1h | Lloyd's syndicate capacity rules |
Workflow 5: Weekly InsurTech KPI Dashboard
{
"nodes": [
{
"id": "1",
"name": "Monday 8 AM",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.2,
"position": [
240,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
}
},
{
"id": "2",
"name": "Platform KPIs",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
460,
200
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT COUNT(*) FILTER (WHERE issued_at >= NOW()-INTERVAL '7d') as policies_issued_week, COUNT(*) FILTER (WHERE opened_at >= NOW()-INTERVAL '7d') as claims_opened_week, SUM(CASE WHEN decision_at IS NOT NULL AND opened_at >= NOW()-INTERVAL '7d' THEN 1 ELSE 0 END) as claims_decided_week FROM policies p LEFT JOIN claims c ON c.policy_id=p.id"
}
},
{
"id": "3",
"name": "Compliance Health",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.5,
"position": [
460,
400
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT COUNT(*) FILTER (WHERE severity='CRITICAL' AND created_at >= NOW()-INTERVAL '7d') as critical_incidents_week, COUNT(*) FILTER (WHERE incident_type='DOI_MARKET_CONDUCT_EXAM_NOTICE' AND resolved_at IS NULL) as open_doi_exams, COUNT(*) FILTER (WHERE incident_type='DATA_BREACH_PHI' AND EXTRACT(YEAR FROM created_at)=EXTRACT(YEAR FROM NOW())) as hipaa_incidents_ytd, COUNT(*) FILTER (WHERE breach_type IS NOT NULL AND detected_at >= NOW()-INTERVAL '7d') as sla_breaches_week FROM insurtech_incidents LEFT JOIN claims_sla_breaches USING(account_id)"
}
},
{
"id": "4",
"name": "Build HTML Dashboard",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
700,
300
],
"parameters": {
"jsCode": "const p=$('Platform KPIs').first().json; const c=$('Compliance Health').first().json; const doiFlag=c.open_doi_exams>0?` [DOI EXAM: ${c.open_doi_exams} OPEN]`:''; const subject=`Weekly InsurTech Dashboard${doiFlag} \u2014 ${new Date().toLocaleDateString('en-US',{month:'short',day:'numeric'})}`; const html=`<h2>Weekly InsurTech Platform Dashboard</h2><table border='1' cellpadding='6'><tr><th>Metric</th><th>This Week</th></tr><tr><td>Policies Issued</td><td>${p.policies_issued_week}</td></tr><tr><td>Claims Opened</td><td>${p.claims_opened_week}</td></tr><tr><td>Claims Decided</td><td>${p.claims_decided_week}</td></tr><tr><td>SLA Breaches</td><td style='color:${c.sla_breaches_week>0?'red':'green'}'>${c.sla_breaches_week}</td></tr></table><h3>Compliance Health</h3><table border='1' cellpadding='6'><tr><th>Item</th><th>Count</th></tr><tr><td>Critical Incidents (7d)</td><td>${c.critical_incidents_week}</td></tr><tr><td>Open DOI Exam Notices</td><td style='color:${c.open_doi_exams>0?'red':'green'}'>${c.open_doi_exams}</td></tr><tr><td>HIPAA Incidents YTD</td><td>${c.hipaa_incidents_ytd}</td></tr></table>`; return [{json:{subject,html}}];"
}
},
{
"id": "5",
"name": "Email CEO",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
920,
200
],
"parameters": {
"operation": "send",
"toList": "ceo@yourcompany.com",
"bccList": "coo@yourcompany.com,actuary@yourcompany.com,cco@yourcompany.com",
"subject": "={{ $json.subject }}",
"message": "={{ $json.html }}",
"options": {
"appendAttribution": false
}
}
},
{
"id": "6",
"name": "Post to Slack",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.2,
"position": [
920,
400
],
"parameters": {
"operation": "message",
"channel": "#exec-kpis",
"text": "={{ `Weekly InsurTech Dashboard posted \u2014 check inbox for full report.\\nOpen DOI exams: ${$('Compliance Health').first().json.open_doi_exams} | SLA breaches: ${$('Compliance Health').first().json.sla_breaches_week}` }}"
}
}
],
"connections": {
"Monday 8 AM": {
"main": [
[
{
"node": "Platform KPIs",
"type": "main",
"index": 0
},
{
"node": "Compliance Health",
"type": "main",
"index": 0
}
]
]
},
"Platform KPIs": {
"main": [
[
{
"node": "Build HTML Dashboard",
"type": "main",
"index": 0
}
]
]
},
"Compliance Health": {
"main": [
[
{
"node": "Build HTML Dashboard",
"type": "main",
"index": 0
}
]
]
},
"Build HTML Dashboard": {
"main": [
[
{
"node": "Email CEO",
"type": "main",
"index": 0
},
{
"node": "Post to Slack",
"type": "main",
"index": 0
}
]
]
}
}
}
What it does: Monday 8 AM — two parallel Postgres queries (platform KPIs + compliance health). Builds an HTML table. Emails CEO (BCC: COO, Chief Actuary, Chief Compliance Officer). Posts summary to Slack #exec-kpis.
Subject line flag: [DOI EXAM: N OPEN] when active DOI market conduct exam notices > 0.
Platform metrics:
- Policies issued this week vs. prior week
- Claims opened / decided / SLA breaches
Compliance metrics:
- Critical incidents past 7 days
- Open DOI exam notices
- HIPAA incidents year-to-date
The Compliance Case for Self-Hosting
Zapier routes your workflow data through Zapier's servers. For InsurTech, that creates four concrete problems:
1. HIPAA: Zapier's standard BAA covers basic file storage. Claims processing automation that touches PHI through Zapier tasks may require a more specific data processing agreement. Self-hosted n8n keeps PHI inside your own VPC — no BAA gymnastics required.
2. DOI Market Conduct Exams: State examiners can request claims automation audit logs going back 3–5 years. Zapier's 30-day retention means your execution logs disappear before the exam period even opens.
3. SOX §302: CEO and CFO must certify that internal controls over financial reporting are adequate. An automation platform with 30-day log retention and no configurable audit trail is a documented control weakness.
4. NAIC Annual Statement data (Schedule D/F financial data): Regulated data with multi-year retention requirements. Stateless automation logs that vanish after 30 days create audit gaps that NAIC examiners will flag.
5. 50-state DOI calendar: 50 states × different annual report deadlines × multiple product lines = hundreds of distinct compliance deadlines. Zapier's scheduler has no built-in multi-tenant deadline tracking per carrier per state — n8n + Postgres handles this natively.
Ship These in Your InsurTech Platform
All 5 workflows are available as ready-to-import n8n templates at FlowKit — n8n Automation Templates.
Individual templates: $12–$29. Full bundle (15 templates): $97.
Top comments (0)