n8n for US InsurTech SaaS: 5 Automations for NAIC Model Laws, Risk-Based Capital, and State DOI Compliance (Free Workflow JSON)
If your InsurTech SaaS serves US insurance carriers, managing general agents (MGAs), surplus lines brokers, or captive insurance managers — your customers operate under one of the most state-fragmented regulatory regimes in the world. The NAIC coordinates, but each state DOI enforces. That means 50+ regulatory environments, overlapping filing deadlines, and zero tolerance for missed notifications.
This post covers 5 production-ready n8n workflows built specifically for US InsurTech SaaS vendors. Each workflow includes full import-ready JSON. Each targets a distinct compliance obligation your customers face — and that your platform can help automate.
Why self-hosted n8n for US insurance compliance?
| Requirement | Cloud iPaaS Risk | Self-Hosted n8n |
|---|---|---|
| NAIC MDL-668 §4 — NPI in automation logs | Third-party data processor relationship | Logs stay in your enclave |
| RBC formula inputs — reinsurance cession data | Proprietary financial data in cloud | Postgres on-prem, no external routing |
| State DOI exam evidence production | Workflow execution logs may be subpoenaed | Git-versioned JSON = auditable evidence |
| NAIC Financial Data Repository (FDR) submissions | Cloud automation = additional CDE touchpoint | Self-hosted n8n = no FDR scope expansion |
| NAIC MAR internal audit trail | 30-day log deletion gaps audit evidence | Unlimited Postgres retention |
| NAIC ORSA — confidential risk assessment | Solvency data in cloud = unauthorized disclosure | Runs in your VPC, no egress |
43 states + DC + Puerto Rico have enacted the NAIC Cybersecurity Model Law (MDL-668). Running your automation through a cloud iPaaS that logs workflow data is, functionally, adding a new third-party service provider to your MDL-668 vendor management program — without a formal risk assessment. Self-hosted n8n eliminates that vector entirely.
Workflow 1: NAIC RBC Ratio Alert Pipeline
Trigger: Scheduled poll every 6 hours against your RBC ratio data
What it does: Reads Risk-Based Capital ratios for each carrier customer, classifies events under the NAIC RBC for P&C Insurers Model Act (MDL-312) action levels, and fires targeted alerts with regulatory deadlines.
NAIC RBC Action Levels:
| RBC Ratio | Action Level | Consequence |
|---|---|---|
| < 100% | Mandatory Control Level (MCL) | State DOI takes control immediately |
| 100–150% | Authorized Control Level (ACL) | Commissioner may place under supervision |
| 150–200% | Regulatory Action Level (RAL) | Commissioner issues corrective order §13 |
| 200–300% | Company Action Level (CAL) | Carrier must file RBC Plan within 45 days §12 |
Why this matters for your SaaS: If your platform processes RBC formula inputs (written premium, loss reserves, reinsurance cessions), your execution logs are financial records subject to state DOI examination. A cloud iPaaS routing those inputs creates an uncontrolled data egress point that your insurance carrier customers' Chief Actuaries will flag.
{
"name": "NAIC RBC Ratio Alert Pipeline",
"nodes": [
{
"id": "1",
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "hours",
"hoursInterval": 6
}
]
}
},
"position": [
240,
300
]
},
{
"id": "2",
"name": "Get RBC Data",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "getAll",
"documentId": "YOUR_SHEET_ID",
"sheetName": "rbc_ratios"
},
"position": [
460,
300
]
},
{
"id": "3",
"name": "Evaluate RBC Level",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "\nconst results = [];\nfor (const row of $input.all()) {\n const d = row.json;\n const rbc = parseFloat(d.rbc_ratio_pct || 0);\n let level = null, urgencyHours = null, action = null;\n if (rbc < 100) {\n level = 'MANDATORY_CONTROL_LEVEL';\n urgencyHours = 24;\n action = 'State DOI takes control \u2014 immediate regulatory intervention';\n } else if (rbc < 150) {\n level = 'AUTHORIZED_CONTROL_LEVEL';\n urgencyHours = 48;\n action = 'Commissioner may place company under supervision';\n } else if (rbc < 200) {\n level = 'REGULATORY_ACTION_LEVEL';\n urgencyHours = 72;\n action = 'Commissioner issues corrective order \u2014 RAL event under NAIC Model Act \u00a713';\n } else if (rbc < 300) {\n level = 'COMPANY_ACTION_LEVEL';\n urgencyHours = 168;\n action = 'Carrier must file RBC Plan with domicile DOI within 45 days \u2014 CAL event \u00a712';\n }\n if (level) {\n results.push({\n json: { ...d, rbc_level: level, urgency_hours: urgencyHours, required_action: action,\n detected_at: new Date().toISOString(),\n naic_model_act_ref: 'NAIC RBC for P&C Insurers Model Act MDL-312 \u00a712-15',\n domicile_doi: d.domicile_state + ' Department of Insurance' }\n });\n }\n}\nreturn results;\n"
},
"position": [
680,
300
]
},
{
"id": "4",
"name": "Alert Slack #rbc-compliance",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#rbc-compliance",
"text": "=\ud83d\udea8 *RBC ALERT \u2014 {{$json.carrier_name}}*\nLevel: {{$json.rbc_level}}\nRBC Ratio: {{$json.rbc_ratio_pct}}%\nRequired Action: {{$json.required_action}}\nUrgency: {{$json.urgency_hours}}h\nRegulatory Ref: {{$json.naic_model_act_ref}}\nDomicile: {{$json.domicile_doi}}"
},
"position": [
900,
240
]
},
{
"id": "5",
"name": "Email Chief Actuary",
"type": "n8n-nodes-base.gmail",
"parameters": {
"toList": "={{$json.chief_actuary_email}}",
"subject": "=[{{$json.rbc_level}}] RBC Ratio Alert \u2014 {{$json.carrier_name}} at {{$json.rbc_ratio_pct}}%",
"message": "=RBC Level: {{$json.rbc_level}}\nRequired Action: {{$json.required_action}}\nDeadline: {{$json.urgency_hours}} hours\n\nRegulatory Reference: {{$json.naic_model_act_ref}}\nDomicile DOI: {{$json.domicile_doi}}\n\nDetected: {{$json.detected_at}}"
},
"position": [
900,
360
]
},
{
"id": "6",
"name": "Log to Postgres",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "insert",
"table": "rbc_alerts",
"columns": "carrier_id,carrier_name,rbc_ratio_pct,rbc_level,urgency_hours,required_action,detected_at"
},
"position": [
900,
480
]
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Get RBC Data",
"type": "main",
"index": 0
}
]
]
},
"Get RBC Data": {
"main": [
[
{
"node": "Evaluate RBC Level",
"type": "main",
"index": 0
}
]
]
},
"Evaluate RBC Level": {
"main": [
[
{
"node": "Alert Slack #rbc-compliance",
"type": "main",
"index": 0
},
{
"node": "Email Chief Actuary",
"type": "main",
"index": 0
},
{
"node": "Log to Postgres",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 2: State DOI Market Conduct Exam Prep Tracker
Trigger: Weekdays 8AM — scans exam schedule for all carrier customers
What it does: Tracks state DOI market conduct examination cycles across your customer base, fires tiered prep alerts, and routes preparation tasks by urgency.
NAIC Market Conduct Examination Standards — Key Timelines:
- OVERDUE/IN PROGRESS: Daily document production tracker — examiner requests answered same-day
- CRITICAL (≤30 days): Prepare document index, brief compliance team, ensure policy files accessible
- URGENT (≤60 days): Complete self-assessment against NAIC Market Regulation Handbook
- WARNING (≤90 days): Gap analysis, identify potential deficiencies before examiners do
- NOTICE (≤180 days): Internal mock exam, procedure documentation update
DOI exam coverage: 45 states use some form of market conduct examination. The NAIC Coordinated Examination Program allows multi-state coordinated exams — one lead state examiner, other states participate. Your carrier customers in states with active examination programs face rolling 3–5 year cycles.
Why the workflow execution logs matter: If your SaaS automates policy issuance, claims routing, or agent appointment workflows, and a state DOI examiner issues a document request during a market conduct exam — your n8n execution logs may be part of the production request. Git-versioned workflow JSON + self-hosted Postgres logs = the audit trail that shows the automation operated as designed.
{
"name": "State DOI Market Conduct Exam Prep Tracker",
"nodes": [
{
"id": "1",
"name": "Weekday 8AM Cron",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1-5"
}
]
}
},
"position": [
240,
300
]
},
{
"id": "2",
"name": "Get Exam Schedule",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "getAll",
"documentId": "YOUR_SHEET_ID",
"sheetName": "doi_exam_schedule"
},
"position": [
460,
300
]
},
{
"id": "3",
"name": "Assess Exam Proximity",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "\nconst alerts = [];\nconst now = new Date();\nfor (const row of $input.all()) {\n const d = row.json;\n if (!d.exam_start_date || d.exam_prep_complete === 'TRUE') continue;\n const examDate = new Date(d.exam_start_date);\n const daysUntil = Math.ceil((examDate - now) / 86400000);\n let tier = null, action = null;\n if (daysUntil < 0) { tier = 'EXAM_IN_PROGRESS'; action = 'Exam underway \u2014 daily document production tracker active'; }\n else if (daysUntil <= 30) { tier = 'CRITICAL'; action = 'Prepare document index, ensure policy files accessible, brief compliance team'; }\n else if (daysUntil <= 60) { tier = 'URGENT'; action = 'Complete self-assessment checklist, identify potential deficiencies'; }\n else if (daysUntil <= 90) { tier = 'WARNING'; action = 'Begin gap analysis against NAIC Market Regulation Handbook'; }\n else if (daysUntil <= 180) { tier = 'NOTICE'; action = 'Schedule internal mock exam, update procedure documentation'; }\n if (tier) alerts.push({ json: { ...d, days_until_exam: daysUntil, prep_tier: tier, prep_action: action,\n naic_ref: 'NAIC Market Regulation Handbook Chapter 21 \u2014 Market Conduct Examination Standards',\n doi_contact: d.state + ' DOI Market Analysis Division' } });\n}\nreturn alerts;\n"
},
"position": [
680,
300
]
},
{
"id": "4",
"name": "Slack #doi-exam-prep",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#doi-exam-prep",
"text": "=\ud83d\udccb *DOI Exam Prep \u2014 {{$json.carrier_name}} ({{$json.state}})*\nTier: {{$json.prep_tier}} | Days Until: {{$json.days_until_exam}}\nAction: {{$json.prep_action}}\nRef: {{$json.naic_ref}}"
},
"position": [
900,
240
]
},
{
"id": "5",
"name": "Email Compliance Lead",
"type": "n8n-nodes-base.gmail",
"parameters": {
"toList": "={{$json.compliance_lead_email}}",
"subject": "=[{{$json.prep_tier}}] DOI Market Conduct Exam \u2014 {{$json.state}} \u2014 {{$json.days_until_exam}} days",
"message": "=Carrier: {{$json.carrier_name}}\nState: {{$json.state}} DOI\nExam Start: {{$json.exam_start_date}}\nDays Until: {{$json.days_until_exam}}\n\nRequired Action: {{$json.prep_action}}\nNAIC Reference: {{$json.naic_ref}}\nDOI Contact: {{$json.doi_contact}}"
},
"position": [
900,
360
]
}
],
"connections": {
"Weekday 8AM Cron": {
"main": [
[
{
"node": "Get Exam Schedule",
"type": "main",
"index": 0
}
]
]
},
"Get Exam Schedule": {
"main": [
[
{
"node": "Assess Exam Proximity",
"type": "main",
"index": 0
}
]
]
},
"Assess Exam Proximity": {
"main": [
[
{
"node": "Slack #doi-exam-prep",
"type": "main",
"index": 0
},
{
"node": "Email Compliance Lead",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 3: NAIC Filing Deadline Tracker
Trigger: Weekdays 7AM — reviews all NAIC filing deadlines across customer base
What it does: Tracks 12 NAIC filing types per carrier customer, deduplicates same-day alerts, routes OVERDUE/CRITICAL events to Slack and compliance email, marks alerts sent to prevent repeat notifications.
Covered NAIC Filing Types:
| Filing | Deadline | Regulatory Basis |
|---|---|---|
| Annual Statement (NAIC FDR) | March 1 | NAIC Blanks Instructions |
| Q1 Quarterly Statement | May 15 | NAIC Blanks Instructions |
| Q2 Quarterly Statement | August 15 | NAIC Blanks Instructions |
| Q3 Quarterly Statement | November 15 | NAIC Blanks Instructions |
| ORSA Summary Report | September 30 | NAIC ORSA Guidance Manual (carriers ≥$500M written premium) |
| MAR Internal Audit | 2 months post fiscal year | NAIC Model Audit Rule MDL-205 |
| MDL-668 Annual Certification | April 15 | NAIC Cybersecurity Model Law §4 |
| Form B Holding Company | April 30 | NAIC Holding Company System Model Act MDL-440 |
| Form C Summary Registration | April 30 | NAIC MDL-440 |
| NAIC IRIS Ratio Review | Rolling | 15 flagged ratios → priority DOI analysis |
| RBC Plan Submission | 45 days from CAL event | NAIC RBC MDL-312 §12 |
| Cybersecurity Incident Report | April 15 annual | NAIC MDL-668 §4K |
{
"name": "NAIC Filing Deadline Tracker",
"nodes": [
{
"id": "1",
"name": "Weekdays 7AM",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 7 * * 1-5"
}
]
}
},
"position": [
240,
300
]
},
{
"id": "2",
"name": "Get NAIC Deadlines",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "getAll",
"documentId": "YOUR_SHEET_ID",
"sheetName": "naic_deadlines"
},
"position": [
460,
300
]
},
{
"id": "3",
"name": "Score Deadlines",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "\nconst today = new Date().toISOString().slice(0,10);\nconst alerts = [];\nfor (const row of $input.all()) {\n const d = row.json;\n if (d.alert_sent_date === today) continue;\n const dueDate = new Date(d.due_date);\n const now = new Date();\n const daysLeft = Math.ceil((dueDate - now) / 86400000);\n const actionMap = {\n 'NAIC_ANNUAL_STATEMENT': 'Annual statement via NAIC Financial Data Repository (FDR) \u2014 March 1',\n 'NAIC_Q1_QUARTERLY': 'Q1 quarterly statement via NAIC FDR \u2014 May 15',\n 'NAIC_Q2_QUARTERLY': 'Q2 quarterly statement via NAIC FDR \u2014 August 15',\n 'NAIC_Q3_QUARTERLY': 'Q3 quarterly statement via NAIC FDR \u2014 November 15',\n 'NAIC_ORSA_ANNUAL': 'ORSA Summary Report to domicile DOI \u2014 September 30 (carriers with $500M+ written premium)',\n 'NAIC_MAR_INTERNAL_AUDIT': 'NAIC Model Audit Rule (MAR) internal audit completion \u2014 2 months post fiscal year',\n 'NAIC_MDL668_CERT': 'NAIC Cybersecurity Model Law MDL-668 annual certification \u2014 April 15',\n 'STATE_DOI_FORM_B': 'Form B Holding Company Annual Registration Statement \u2014 April 30',\n 'STATE_DOI_FORM_C': 'Form C Summary Registration \u2014 April 30',\n 'NAIC_IRIS_RATIO_REVIEW': 'NAIC IRIS ratio review \u2014 15 flagged ratios trigger priority DOI analysis',\n 'RBC_PLAN_SUBMISSION': 'RBC Plan to domicile DOI \u2014 45 days from CAL event',\n 'NAIC_CYBERSECURITY_INCIDENT_REPORT': 'NAIC MDL-668 cybersecurity event annual report \u2014 April 15'\n };\n let tier = null;\n if (daysLeft < 0) tier = 'OVERDUE';\n else if (daysLeft <= 14) tier = 'CRITICAL';\n else if (daysLeft <= 30) tier = 'URGENT';\n else if (daysLeft <= 60) tier = 'WARNING';\n else if (daysLeft <= 90) tier = 'NOTICE';\n if (tier) alerts.push({ json: { ...d, days_left: daysLeft, tier, required_action: actionMap[d.deadline_type] || d.deadline_type, alert_sent_date: today } });\n}\nreturn alerts;\n"
},
"position": [
680,
300
]
},
{
"id": "4",
"name": "Route by Tier",
"type": "n8n-nodes-base.switch",
"parameters": {
"rules": {
"rules": [
{
"value1": "={{$json.tier}}",
"operation": "equals",
"value2": "OVERDUE"
},
{
"value1": "={{$json.tier}}",
"operation": "equals",
"value2": "CRITICAL"
},
{
"value1": "={{$json.tier}}",
"operation": "equals",
"value2": "URGENT"
}
]
}
},
"position": [
900,
300
]
},
{
"id": "5",
"name": "Urgent Slack",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#naic-compliance",
"text": "=\u26a0\ufe0f *NAIC Filing Alert \u2014 {{$json.tier}}*\n{{$json.carrier_name}} | {{$json.deadline_type}}\nDue: {{$json.due_date}} ({{$json.days_left}} days)\nAction: {{$json.required_action}}"
},
"position": [
1120,
240
]
},
{
"id": "6",
"name": "Email All",
"type": "n8n-nodes-base.gmail",
"parameters": {
"toList": "={{$json.compliance_email}}",
"subject": "=[{{$json.tier}}] NAIC Filing Deadline \u2014 {{$json.deadline_type}} \u2014 {{$json.days_left}} days",
"message": "=Carrier: {{$json.carrier_name}}\nDeadline Type: {{$json.deadline_type}}\nDue Date: {{$json.due_date}}\nDays Remaining: {{$json.days_left}}\n\nRequired Action: {{$json.required_action}}"
},
"position": [
1120,
360
]
},
{
"id": "7",
"name": "Mark Alert Sent",
"type": "n8n-nodes-base.googleSheets",
"parameters": {
"operation": "update",
"documentId": "YOUR_SHEET_ID",
"sheetName": "naic_deadlines",
"columns": {
"mappingMode": "defineBelow",
"value": {
"alert_sent_date": "={{$json.alert_sent_date}}"
}
}
},
"position": [
1120,
480
]
}
],
"connections": {
"Weekdays 7AM": {
"main": [
[
{
"node": "Get NAIC Deadlines",
"type": "main",
"index": 0
}
]
]
},
"Get NAIC Deadlines": {
"main": [
[
{
"node": "Score Deadlines",
"type": "main",
"index": 0
}
]
]
},
"Score Deadlines": {
"main": [
[
{
"node": "Route by Tier",
"type": "main",
"index": 0
}
]
]
},
"Route by Tier": {
"main": [
[
{
"node": "Urgent Slack",
"type": "main",
"index": 0
}
],
[
{
"node": "Urgent Slack",
"type": "main",
"index": 0
}
],
[
{
"node": "Email All",
"type": "main",
"index": 0
}
]
]
},
"Urgent Slack": {
"main": [
[
{
"node": "Email All",
"type": "main",
"index": 0
}
]
]
},
"Email All": {
"main": [
[
{
"node": "Mark Alert Sent",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 4: NAIC MDL-668 Cybersecurity Breach Incident Pipeline
Trigger: Webhook — fires immediately when a cybersecurity event is detected
What it does: Receives cybersecurity event notifications from your platform (or your customer's SIEM), classifies the event under NAIC MDL-668 definitions, calculates the domicile DOI notification deadline (72 hours for NPI-involving events), deduplicates within 30-minute windows, and fires CISO + legal alerts with pre-calculated deadlines.
NAIC MDL-668 Event Classification:
| Event Type | Severity | DOI Notification | Regulatory Basis |
|---|---|---|---|
| NPI Cybersecurity Event | CRITICAL | 72 hours | MDL-668 §4F |
| Ransomware Attack | CRITICAL | 72 hours | MDL-668 §4F — system encryption = event |
| Third-Party Provider Breach | HIGH | 72 hours | MDL-668 §4G |
| Insider Data Exfiltration | CRITICAL | 72 hours | MDL-668 §4F |
| API Credential Compromise (with NPI) | HIGH | 72 hours | MDL-668 §4F |
| Phishing with NPI Access | HIGH | 72 hours | MDL-668 §4F |
| System Intrusion (no confirmed NPI) | MEDIUM | 168 hours | MDL-668 §4 — assess exposure |
The self-hosting argument here is unusually strong: MDL-668 §4 requires that a Licensee's cybersecurity program hold NPI 'in strictest confidence.' The workflow execution logs for a breach detection automation — which by definition process breach event data including policyholder NPI — must not themselves egress to a cloud vendor's servers. Self-hosted n8n keeps those incident logs in your Postgres instance, available for the mandatory MDL-668 §4K annual report and any subsequent DOI examination.
{
"name": "NAIC MDL-668 Cybersecurity Breach Pipeline",
"nodes": [
{
"id": "1",
"name": "Cybersecurity Event Webhook",
"type": "n8n-nodes-base.webhook",
"parameters": {
"path": "naic-cyber-event",
"responseMode": "responseNode"
},
"position": [
240,
300
]
},
{
"id": "2",
"name": "Classify & Deduplicate",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "\nconst d = $input.first().json;\nconst eventId = d.event_id || (d.carrier_id + '_' + d.event_type + '_' + Date.now());\nconst stateStore = $getWorkflowStaticData('global');\nconst dedup = stateStore.cyber_events || {};\nif (dedup[eventId] && (Date.now() - dedup[eventId]) < 1800000) return [];\ndedup[eventId] = Date.now();\nstateStore.cyber_events = dedup;\n\nconst eventMap = {\n 'CYBERSECURITY_EVENT_NPI': { severity: 'CRITICAL', notifyHours: 72, ref: 'NAIC MDL-668 \u00a74F \u2014 notify domicile DOI within 72h', scope: 'Nonpublic Personal Information accessed/acquired by unauthorized person' },\n 'RANSOMWARE_ATTACK': { severity: 'CRITICAL', notifyHours: 72, ref: 'NAIC MDL-668 \u00a74F \u2014 72h domicile DOI notification', scope: 'System encryption constitutes cybersecurity event' },\n 'THIRD_PARTY_BREACH': { severity: 'HIGH', notifyHours: 72, ref: 'NAIC MDL-668 \u00a74G \u2014 third-party service provider breach notification', scope: 'Third-party provider breach affecting carrier NPI' },\n 'INSIDER_DATA_EXFILTRATION': { severity: 'CRITICAL', notifyHours: 72, ref: 'NAIC MDL-668 \u00a74F \u2014 employee exfiltration = cybersecurity event', scope: 'Unauthorized acquisition by employee/contractor' },\n 'API_CREDENTIAL_COMPROMISE': { severity: 'HIGH', notifyHours: 72, ref: 'NAIC MDL-668 \u00a74F \u2014 credential compromise with NPI access', scope: 'API key compromise with access to policyholder data' },\n 'PHISHING_WITH_ACCESS': { severity: 'HIGH', notifyHours: 72, ref: 'NAIC MDL-668 \u00a74F \u2014 phishing resulting in NPI access', scope: 'Successful phishing leading to unauthorized NPI access' },\n 'SYSTEM_INTRUSION_NO_NPI': { severity: 'MEDIUM', notifyHours: 168, ref: 'NAIC MDL-668 \u00a74 \u2014 log and assess NPI exposure', scope: 'System intrusion without confirmed NPI access \u2014 assess and document' }\n};\nconst cfg = eventMap[d.event_type] || { severity: 'MEDIUM', notifyHours: 168, ref: 'NAIC MDL-668 \u00a74 \u2014 assess and document', scope: 'Unknown event type' };\nconst detected = new Date();\nconst notifyDeadline = new Date(detected.getTime() + cfg.notifyHours * 3600000);\nreturn [{ json: { ...d, event_id: eventId, severity: cfg.severity, notify_hours: cfg.notifyHours,\n notification_deadline: notifyDeadline.toISOString(),\n regulatory_ref: cfg.ref, scope_description: cfg.scope,\n detected_at: detected.toISOString(),\n naic_mdl668_states: '43 states + DC + PR enacted NAIC MDL-668 as of 2025',\n domicile_doi_notification: d.domicile_state + ' DOI within ' + cfg.notifyHours + 'h \u2014 file via state cybersecurity portal' } }];\n"
},
"position": [
460,
300
]
},
{
"id": "3",
"name": "Slack #cyber-incident",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#cyber-incident",
"text": "=\ud83d\udd34 *NAIC MDL-668 Cybersecurity Event \u2014 {{$json.severity}}*\nCarrier: {{$json.carrier_name}}\nEvent: {{$json.event_type}}\nScope: {{$json.scope_description}}\nNotify DOI By: {{$json.notification_deadline}}\nRegulatory Ref: {{$json.regulatory_ref}}\nJurisdiction: {{$json.naic_mdl668_states}}"
},
"position": [
680,
240
]
},
{
"id": "4",
"name": "Email CISO + Legal",
"type": "n8n-nodes-base.gmail",
"parameters": {
"toList": "={{$json.ciso_email}}",
"ccList": "={{$json.legal_email}}",
"subject": "=[NAIC MDL-668 {{$json.severity}}] Cybersecurity Event \u2014 {{$json.carrier_name}} \u2014 Notify DOI by {{$json.notification_deadline}}",
"message": "=Event Type: {{$json.event_type}}\nSeverity: {{$json.severity}}\nScope: {{$json.scope_description}}\nDetected: {{$json.detected_at}}\nDOI Notification Deadline: {{$json.notification_deadline}}\n\nRegulatory Reference: {{$json.regulatory_ref}}\nApplicable Jurisdictions: {{$json.naic_mdl668_states}}\nDomicile DOI Action: {{$json.domicile_doi_notification}}"
},
"position": [
680,
360
]
},
{
"id": "5",
"name": "Log to Postgres",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "insert",
"table": "naic_cyber_events",
"columns": "event_id,carrier_id,carrier_name,event_type,severity,notify_hours,notification_deadline,regulatory_ref,detected_at"
},
"position": [
680,
480
]
},
{
"id": "6",
"name": "Respond 200",
"type": "n8n-nodes-base.respondToWebhook",
"parameters": {
"responseCode": 200,
"responseBody": "={\"status\":\"received\",\"event_id\":\"{{$json.event_id}}\",\"notification_deadline\":\"{{$json.notification_deadline}}\"}"
},
"position": [
900,
300
]
}
],
"connections": {
"Cybersecurity Event Webhook": {
"main": [
[
{
"node": "Classify & Deduplicate",
"type": "main",
"index": 0
}
]
]
},
"Classify & Deduplicate": {
"main": [
[
{
"node": "Slack #cyber-incident",
"type": "main",
"index": 0
},
{
"node": "Email CISO + Legal",
"type": "main",
"index": 0
},
{
"node": "Log to Postgres",
"type": "main",
"index": 0
}
]
]
},
"Log to Postgres": {
"main": [
[
{
"node": "Respond 200",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 5: Weekly US InsurTech Platform KPI Dashboard
Trigger: Every Monday 8AM — queries dual Postgres tables, builds conditional HTML report
What it does: Aggregates RBC ratio health, open critical compliance events, and upcoming NAIC filing deadlines across your entire US carrier customer base. Flags subject line with [RBC CAL BREACH] or [CRITICAL OPEN] when action is needed. Emails CEO + CFO with CISO BCC.
{
"name": "Weekly US InsurTech SaaS KPI Dashboard",
"nodes": [
{
"id": "1",
"name": "Monday 8AM",
"type": "n8n-nodes-base.scheduleTrigger",
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
},
"position": [
240,
300
]
},
{
"id": "2",
"name": "Query Customer Health",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "executeQuery",
"query": "SELECT COUNT(*) as total_carriers, COUNT(CASE WHEN rbc_ratio_pct < 200 THEN 1 END) as rbc_below_cal, COUNT(CASE WHEN rbc_ratio_pct < 150 THEN 1 END) as rbc_below_ral, AVG(rbc_ratio_pct) as avg_rbc_ratio FROM carrier_customers WHERE is_active = true"
},
"position": [
460,
240
]
},
{
"id": "3",
"name": "Query Compliance Events",
"type": "n8n-nodes-base.postgres",
"parameters": {
"operation": "executeQuery",
"query": "SELECT COUNT(CASE WHEN severity = 'CRITICAL' AND resolved = false THEN 1 END) as open_critical, COUNT(CASE WHEN event_date >= NOW() - INTERVAL '7 days' THEN 1 END) as events_this_week, COUNT(CASE WHEN deadline_date <= NOW() + INTERVAL '30 days' AND completed = false THEN 1 END) as deadlines_30d FROM naic_compliance_events"
},
"position": [
460,
400
]
},
{
"id": "4",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"parameters": {
"mode": "combine",
"combinationMode": "multiplex"
},
"position": [
680,
300
]
},
{
"id": "5",
"name": "Build KPI Report",
"type": "n8n-nodes-base.code",
"parameters": {
"jsCode": "\nconst health = $input.first().json;\nconst events = $('Query Compliance Events').first().json;\nconst rbcFlag = parseInt(health.rbc_below_cal) > 0 ? ' [RBC CAL BREACH]' : '';\nconst critFlag = parseInt(events.open_critical) > 0 ? ' [CRITICAL OPEN]' : '';\nconst subject = '[US InsurTech KPI' + rbcFlag + critFlag + '] Weekly Dashboard \u2014 ' + new Date().toISOString().slice(0,10);\nconst html = `\n<h2>FlowKit US InsurTech SaaS \u2014 Weekly KPI</h2>\n<table border='1' style='border-collapse:collapse;width:100%'>\n<tr style='background:#1a1a2e;color:white'><th>Metric</th><th>Value</th><th>Status</th></tr>\n<tr><td>Total Active Carriers</td><td>${health.total_carriers}</td><td>-</td></tr>\n<tr><td>RBC Below CAL (<200%)</td><td>${health.rbc_below_cal}</td><td style='color:${health.rbc_below_cal>0?\"red\":\"green\"}'>${health.rbc_below_cal>0?'NEEDS ATTENTION':'OK'}</td></tr>\n<tr><td>RBC Below RAL (<150%)</td><td>${health.rbc_below_ral}</td><td style='color:${health.rbc_below_ral>0?\"darkred\":\"green\"}'>${health.rbc_below_ral>0?'CRITICAL':'OK'}</td></tr>\n<tr><td>Avg RBC Ratio</td><td>${parseFloat(health.avg_rbc_ratio||0).toFixed(1)}%</td><td>-</td></tr>\n<tr><td>Open Critical Events</td><td>${events.open_critical}</td><td style='color:${events.open_critical>0?\"red\":\"green\"}'>${events.open_critical>0?'ACTION REQUIRED':'Clear'}</td></tr>\n<tr><td>Compliance Events (7d)</td><td>${events.events_this_week}</td><td>-</td></tr>\n<tr><td>Deadlines Next 30 Days</td><td>${events.deadlines_30d}</td><td style='color:${events.deadlines_30d>3?\"orange\":\"green\"}'>${events.deadlines_30d>3?'REVIEW QUEUE':'Manageable'}</td></tr>\n</table>\n<p><small>NAIC RBC Model Act MDL-312 | NAIC MDL-668 Cybersecurity | NAIC Market Regulation Handbook</small></p>`;\nreturn [{ json: { subject, html_body: html } }];\n"
},
"position": [
900,
300
]
},
{
"id": "6",
"name": "Email CEO + CFO",
"type": "n8n-nodes-base.gmail",
"parameters": {
"toList": "ceo@yourcompany.com,cfo@yourcompany.com",
"ccList": "ciso@yourcompany.com",
"subject": "={{$json.subject}}",
"message": "={{$json.html_body}}",
"options": {
"appendAttribution": false
}
},
"position": [
1120,
240
]
},
{
"id": "7",
"name": "Slack #exec-insurtech-kpis",
"type": "n8n-nodes-base.slack",
"parameters": {
"channel": "#exec-insurtech-kpis",
"text": "=US InsurTech KPI posted \u2014 check email for full dashboard."
},
"position": [
1120,
360
]
}
],
"connections": {
"Monday 8AM": {
"main": [
[
{
"node": "Query Customer Health",
"type": "main",
"index": 0
},
{
"node": "Query Compliance Events",
"type": "main",
"index": 0
}
]
]
},
"Query Customer Health": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Query Compliance Events": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Merge": {
"main": [
[
{
"node": "Build KPI Report",
"type": "main",
"index": 0
}
]
]
},
"Build KPI Report": {
"main": [
[
{
"node": "Email CEO + CFO",
"type": "main",
"index": 0
},
{
"node": "Slack #exec-insurtech-kpis",
"type": "main",
"index": 0
}
]
]
}
}
}
Key US InsurTech Compliance Angles
1. NAIC ORSA — confidentiality requirements
The Own Risk and Solvency Assessment (ORSA) Summary Report is a confidential regulatory filing. It contains proprietary actuarial assumptions, stress test scenarios, and internal capital models. Running ORSA data preparation workflows through a cloud-hosted automation platform routes that data to the vendor's infrastructure — outside the carrier's confidential regulatory process. NAIC's ORSA Guidance Manual emphasizes that ORSA is 'confidential and protected from public disclosure.'
2. NAIC IRIS Ratios — early warning system
The NAIC Insurance Regulatory Information System (IRIS) calculates 13 financial ratios from annual statement data. Carriers with 4+ flagged ratios get priority DOI analysis. Automating IRIS ratio monitoring lets your SaaS platform give carriers advance warning before the DOI flags them — a retention-driving capability that Zapier-dependent competitors can't deliver without NPI data egress.
3. NAIC MDL-668 — the 43-state vendor management hook
Under MDL-668, carriers must maintain 'a program to oversee and manage the cybersecurity risks associated with third-party service providers.' That means: if your SaaS uses a cloud automation vendor (Zapier, Make), that vendor is in scope for the carrier's MDL-668 §4G third-party oversight program — adding audit burden to your carrier customer's already-crowded compliance calendar. Self-hosted n8n removes that conversation entirely.
4. State DOI examination scope — automation as evidence
State DOI market conduct examiners are increasingly issuing document requests that include 'all automated processes used in connection with policy issuance, claims handling, or agent appointment.' If your SaaS uses automation, those workflows are potentially in scope for production. Git-versioned n8n workflow JSON files, stored in your own infrastructure, are the ideal response — version history proves the workflow operated as designed at any point in time.
5. NAIC RBC Plan filing — 45-day clock under CAL
When a carrier hits Company Action Level (RBC ratio 200–300%), NAIC MDL-312 §12 requires the carrier to file an RBC Plan with the domicile DOI within 45 calendar days. That's a hard regulatory deadline that your platform's automation tracking can surface days or weeks before your carrier customer's internal compliance team catches it — creating a concrete, quantifiable retention and upsell argument.
Five Buyer Questions — US InsurTech SaaS Edition
Q: Our carrier customers are already using Zapier. Why switch?
A: Because under NAIC MDL-668, the carrier's Chief Compliance Officer has to manage Zapier as a third-party service provider — with annual risk assessments and vendor questionnaires. Self-hosted n8n removes Zapier from their MDL-668 §4G vendor list entirely. That's one fewer vendor for their annual cybersecurity program review, and it eliminates the 'third-party breach via automation vendor' scenario from their RBC plan.
Q: Do we need to worry about NAIC ORSA data residency?
A: Yes. ORSA Summary Reports contain the carrier's internal capital model, stress scenarios, and forward-looking solvency projections. These are confidential regulatory documents — routing their preparation data through a cloud platform means that data touches the vendor's infrastructure. Self-hosted n8n keeps ORSA workflow data in the carrier's own VPC or on-premise environment.
Q: How does n8n handle the 72-hour MDL-668 notification clock?
A: Workflow 4 above calculates the notification deadline at event detection time and surfaces it immediately to CISO and legal. The Postgres log becomes the evidence record for MDL-668 §4K annual reporting — showing that each cybersecurity event was detected, classified, and notified within the required window.
Q: What if a state DOI examiner requests our workflow execution logs?
A: Self-hosted n8n + Postgres means you control those logs completely. You can export them in whatever format the examiner requests, with full timestamp and version history. A cloud-hosted automation vendor would require a separate legal process, may have 30-day log deletion policies that create gaps, and introduces a third party into the examination process.
Q: Does this work for MGAs and surplus lines brokers too?
A: Yes — Workflows 2 and 3 are configurable by state and license type. MGAs face state DOI examination cycles on admitted business, and surplus lines brokers must track stamping office filings by state. The deadline tracker schema can be extended to cover stamping office submission deadlines, surplus lines tax filings, and eligibility list maintenance across all 50 states.
All 5 workflows are free to import. Ready-to-use n8n workflow templates for compliance-heavy verticals: stripeai.gumroad.com
Next in this series: EU InsurTech — Solvency II EIOPA/Lloyd's/GDPR Art.9 (already published), RegTech SaaS — MiFID II/DORA/AMLD6, FinTech SaaS — PCI DSS/SOX/GLBA.
Top comments (0)