DEV Community

Alex Kane
Alex Kane

Posted on

n8n for WealthTech/RIA SaaS Vendors: 5 Automations for SEC Books & Records, FINRA Supervision, ERISA Fiduciary, and DOL Compliance

If your SaaS platform serves registered investment advisers, broker-dealers, or ERISA fiduciaries — you inherit a piece of their compliance obligation. Client portfolio data, trade records, complaints, and communications flowing through your platform touch SEC Books & Records (Rule 204-2), FINRA Rules 4511/4512/4530, ERISA §404 fiduciary standards, and DOL prohibited transaction rules.

Routing that data through a cloud iPaaS like Zapier or Make creates a third-party data processor that isn't in your client's compliance documentation — and it won't appear in a Form ADV disclosure or an SEC examination response.

Self-hosted n8n on your own infrastructure keeps the automation layer inside your compliance boundary. Here are 5 production-ready workflows with full JSON.


1. New RIA Client Onboarding Drip (7-Tier Segmentation + Compliance Flags)

Segments by client tier and injects Form CRS / Form ADV Part 2 disclosure links on Day 0, integration guidance on Day 3, and a QBR/upgrade offer on Day 14.

Customer tiers: LARGE_RIA_ENTERPRISE (>$10B AUM) / MIDMARKET_RIA ($1B–$10B AUM) / SMALL_RIA_STARTUP (<$1B AUM) / BROKER_DEALER / HYBRID_BD_RIA / FAMILY_OFFICE / ROBO_ADVISOR_PLATFORM

Compliance flags: SEC_RIA_REGISTERED / FINRA_MEMBER / ERISA_FIDUCIARY_ADVISOR / DOL_FIDUCIARY_RULE_APPLICABLE / SEC_REG_BI_COVERED / CFTC_REGULATED / SOC2_REQUIRED

{
  "name": "WealthTech RIA Onboarding Drip",
  "nodes": [
    {
      "id": "1",
      "name": "New Client Webhook",
      "type": "n8n-nodes-base.webhook",
      "parameters": {
        "path": "wealthtech-onboarding",
        "method": "POST"
      }
    },
    {
      "id": "2",
      "name": "Extract & Segment",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const d=items[0].json;const tiers={LARGE_RIA_ENTERPRISE:{minAum:10000000000,csmSlack:'#enterprise-cs',qbrDay:7},MIDMARKET_RIA:{minAum:1000000000,csmSlack:'#mid-market-cs',qbrDay:10},SMALL_RIA_STARTUP:{minAum:0,csmSlack:'#startup-cs',qbrDay:14},BROKER_DEALER:{csmSlack:'#bd-cs',qbrDay:10},HYBRID_BD_RIA:{csmSlack:'#hybrid-cs',qbrDay:12},FAMILY_OFFICE:{csmSlack:'#fo-cs',qbrDay:10},ROBO_ADVISOR_PLATFORM:{csmSlack:'#robo-cs',qbrDay:14}};const tier=d.tier||'SMALL_RIA_STARTUP';const t=tiers[tier]||tiers.SMALL_RIA_STARTUP;const flags=d.compliance_flags||[];const secRia=flags.includes('SEC_RIA_REGISTERED');const finra=flags.includes('FINRA_MEMBER');const erisa=flags.includes('ERISA_FIDUCIARY_ADVISOR');const regBi=flags.includes('SEC_REG_BI_COVERED');return [{json:{...d,tier,csmSlack:t.csmSlack,qbrDay:t.qbrDay,secRia,finra,erisa,regBi,day0Subject:`Welcome to [Platform] \u2014 Your SEC/FINRA Compliance Toolkit`}}];"
      }
    },
    {
      "id": "3",
      "name": "Day 0 Welcome + Form CRS/ADV",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "operation": "send",
        "toEmail": "={{$json.email}}",
        "subject": "={{$json.day0Subject}}",
        "message": "={{`Dear ${$json.contact_name},\\n\\nWelcome to [Platform]. As a ${$json.tier.replace(/_/g,' ')}, your account includes:\\n\\n\u2022 Form CRS delivery automation (SEC Reg BI requirement)\\n\u2022 Form ADV Part 2 disclosure tracking\\n${$json.finra?'\u2022 FINRA Rule 4530 complaint routing\\n':''}${$json.erisa?'\u2022 ERISA \u00a7404 fiduciary documentation workflows\\n':''}\\nYour Form CRS/ADV links are pre-loaded in your dashboard. Your CSM will reach out within 1 business day.\\n\\n[Platform] Team`}"
      }
    },
    {
      "id": "4",
      "name": "Log Onboarding",
      "type": "n8n-nodes-base.googleSheets",
      "parameters": {
        "operation": "appendOrUpdate",
        "sheetId": "YOUR_SHEET_ID",
        "range": "Onboarding!A:H",
        "columns": {
          "mappingMode": "autoMapInputData"
        }
      }
    },
    {
      "id": "5",
      "name": "Slack CSM Alert",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "={{$json.csmSlack}}",
        "text": "={{`New ${$json.tier} client: ${$json.company_name} (${$json.email}). SEC RIA: ${$json.secRia} | FINRA: ${$json.finra} | ERISA: ${$json.erisa}`}}"
      }
    },
    {
      "id": "6",
      "name": "Wait 3 Days",
      "type": "n8n-nodes-base.wait",
      "parameters": {
        "amount": 3,
        "unit": "days"
      }
    },
    {
      "id": "7",
      "name": "Day 3 Integration Guide",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "operation": "send",
        "toEmail": "={{$json.email}}",
        "subject": "Your SEC/FINRA integration setup \u2014 3 quick steps",
        "message": "={{`Hi ${$json.contact_name},\\n\\nHere are the 3 integrations your compliance team should configure this week:\\n\\n1. Connect your CRM/AUM data source for automated Books & Records (Rule 204-2)\\n2. Set up the FINRA 4530 complaint routing webhook\\n3. Configure your Form CRS delivery triggers\\n\\nSetup guide: [docs link]\\n\\n[Platform] Team`}"
      }
    },
    {
      "id": "8",
      "name": "Wait to QBR Day",
      "type": "n8n-nodes-base.wait",
      "parameters": {
        "amount": "={{$json.qbrDay}}",
        "unit": "days"
      }
    },
    {
      "id": "9",
      "name": "Day 14 QBR Offer",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "operation": "send",
        "toEmail": "={{$json.email}}",
        "subject": "Book your 30-min compliance automation review",
        "message": "={{`Hi ${$json.contact_name},\\n\\nYou've been using [Platform] for ${$json.qbrDay} days. Let's review your SEC/FINRA automation setup and identify any gaps before your next examination.\\n\\nBook a 30-min call: [calendar link]\\n\\n[Platform] Team`}"
      }
    }
  ],
  "connections": {
    "New Client Webhook": {
      "main": [
        [
          {
            "node": "Extract & Segment"
          }
        ]
      ]
    },
    "Extract & Segment": {
      "main": [
        [
          {
            "node": "Day 0 Welcome + Form CRS/ADV"
          }
        ]
      ]
    },
    "Day 0 Welcome + Form CRS/ADV": {
      "main": [
        [
          {
            "node": "Log Onboarding"
          }
        ]
      ]
    },
    "Log Onboarding": {
      "main": [
        [
          {
            "node": "Slack CSM Alert"
          }
        ]
      ]
    },
    "Slack CSM Alert": {
      "main": [
        [
          {
            "node": "Wait 3 Days"
          }
        ]
      ]
    },
    "Wait 3 Days": {
      "main": [
        [
          {
            "node": "Day 3 Integration Guide"
          }
        ]
      ]
    },
    "Day 3 Integration Guide": {
      "main": [
        [
          {
            "node": "Wait to QBR Day"
          }
        ]
      ]
    },
    "Wait to QBR Day": {
      "main": [
        [
          {
            "node": "Day 14 QBR Offer"
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Self-hosting note: Client AUM data, CRM records, and Form CRS delivery logs are Books & Records subject to SEC Rule 204-2. Routing them through Zapier/Make creates a cloud processor not documented in your Form ADV — an immediate SOC2 vendor risk finding and a potential SEC examination deficiency.


2. SEC Books & Records / FINRA API Health Monitor

Polls 5 critical platform endpoints every 5 minutes. Annotates each failure with the specific regulatory exposure.

{
  "name": "WealthTech API Health Monitor",
  "nodes": [
    {
      "id": "1",
      "name": "Every 5 Minutes",
      "type": "n8n-nodes-base.scheduleTrigger",
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "minutes",
              "minutesInterval": 5
            }
          ]
        }
      }
    },
    {
      "id": "2",
      "name": "Load Endpoints",
      "type": "n8n-nodes-base.googleSheets",
      "parameters": {
        "operation": "getAll",
        "sheetId": "YOUR_SHEET_ID",
        "range": "Endpoints!A:D"
      }
    },
    {
      "id": "3",
      "name": "Poll Each Endpoint",
      "type": "n8n-nodes-base.httpRequest",
      "parameters": {
        "url": "={{$json.endpoint_url}}",
        "method": "GET",
        "timeout": 8000,
        "continueOnFail": true
      }
    },
    {
      "id": "4",
      "name": "Classify Failures",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const results=[];for(const item of items){const ep=item.json;const ok=ep.statusCode>=200&&ep.statusCode<300;if(!ok){const regulatoryMap={books_records_api:'SEC Rule 204-2 \u2014 Books & Records preservation obligation. Failure = potential examination finding.',form_crs_delivery_api:'SEC Reg BI Form CRS \u2014 required delivery within 10 business days of account opening. Downtime = client disclosure failure.',finra_complaint_api:'FINRA Rule 4530 \u2014 customer complaint reporting within 30 days. Missed routing = late filing.',erisa_reporting_api:'ERISA \u00a7404 fiduciary \u2014 investment advice records must be accessible on demand by DOL.',aml_kyc_api:'FinCEN / BSA \u2014 AML program records must be available within 72h of government request.'};const reg=regulatoryMap[ep.endpoint_name]||'Unknown regulatory exposure.';results.push({json:{endpoint_name:ep.endpoint_name,status:ep.statusCode||'TIMEOUT',regulatory_note:reg,ts:new Date().toISOString()}});}}return results.length?results:[{json:{status:'ALL_OK',ts:new Date().toISOString()}}];"
      }
    },
    {
      "id": "5",
      "name": "Only Failures",
      "type": "n8n-nodes-base.if",
      "parameters": {
        "conditions": {
          "string": [
            {
              "value1": "={{$json.status}}",
              "operation": "notEqual",
              "value2": "ALL_OK"
            }
          ]
        }
      }
    },
    {
      "id": "6",
      "name": "Slack #compliance-ops",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "#compliance-ops",
        "text": "={{`:rotating_light: ${$json.endpoint_name} DOWN (${$json.status})\\n*Regulatory note*: ${$json.regulatory_note}\\nTime: ${$json.ts}`}}"
      }
    },
    {
      "id": "7",
      "name": "Log to Sheets",
      "type": "n8n-nodes-base.googleSheets",
      "parameters": {
        "operation": "appendOrUpdate",
        "sheetId": "YOUR_SHEET_ID",
        "range": "Incidents!A:D"
      }
    }
  ],
  "connections": {
    "Every 5 Minutes": {
      "main": [
        [
          {
            "node": "Load Endpoints"
          }
        ]
      ]
    },
    "Load Endpoints": {
      "main": [
        [
          {
            "node": "Poll Each Endpoint"
          }
        ]
      ]
    },
    "Poll Each Endpoint": {
      "main": [
        [
          {
            "node": "Classify Failures"
          }
        ]
      ]
    },
    "Classify Failures": {
      "main": [
        [
          {
            "node": "Only Failures"
          }
        ]
      ]
    },
    "Only Failures": {
      "main": [
        [
          {
            "node": "Slack #compliance-ops"
          }
        ],
        []
      ]
    },
    "Slack #compliance-ops": {
      "main": [
        [
          {
            "node": "Log to Sheets"
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Endpoint names to configure: books_records_api, form_crs_delivery_api, finra_complaint_api, erisa_reporting_api, aml_kyc_api


3. SEC/FINRA/ERISA/DOL Compliance Deadline Tracker

Runs weekdays at 8 AM. Routes at 120/90/60/30/14 day thresholds. Escalates critical items to VP Compliance with CC to outside counsel.

12 deadline types tracked:

Deadline Regulation Typical Window
SEC_ADV_ANNUAL_AMENDMENT 17 CFR §275.204-1 March 31 each year
SEC_FORM_CRS_MATERIAL_UPDATE SEC Reg BI §17 CFR §275.204-3 Within 30 days of material change
FINRA_4530_COMPLAINT_REPORT FINRA Rule 4530(a) 30 calendar days of quarter-end
FINRA_ANNUAL_COMPLIANCE_CERT FINRA Rule 3130 Within 1 year of prior cert
ERISA_DOL_FORM_5500_ANNUAL ERISA §104 / 29 CFR §2520.104a-5 July 31 (calendar year plans)
DOL_FIDUCIARY_QUARTERLY_DISCLOSURE DOL PTE 2020-02 §V(b) Within 45 days after each quarter
SEC_BOOKS_RECORDS_AUDIT_READINESS SEC Rule 204-2 3-year accessible / 6-year total
SEC_MARKETING_RULE_ANNUAL_REVIEW 17 CFR §275.206(4)-1 Annual compliance review
FINRA_SUPERVISORY_PROCEDURE_REVIEW FINRA Rule 3110 Annual update required
SOC2_TYPE2_RENEWAL AICPA SOC2 Annual audit cycle
ISO27001_SURVEILLANCE ISO 27001:2022 Annual surveillance audit
ANNUAL_PENTEST SOC2 CC7.1 / best practice Annual
{
  "name": "WealthTech Compliance Deadline Tracker",
  "nodes": [
    {
      "id": "1",
      "name": "Weekdays 8 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1-5"
            }
          ]
        }
      }
    },
    {
      "id": "2",
      "name": "Load Deadlines",
      "type": "n8n-nodes-base.googleSheets",
      "parameters": {
        "operation": "getAll",
        "sheetId": "YOUR_SHEET_ID",
        "range": "Deadlines!A:F"
      }
    },
    {
      "id": "3",
      "name": "Calculate Urgency",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const today=new Date();const out=[];for(const item of items){const d=item.json;if(!d.due_date||d.status==='COMPLETE')continue;const due=new Date(d.due_date);const days=Math.round((due-today)/(86400000));let severity,action;if(days<0){severity='OVERDUE';action='IMMEDIATE \u2014 file or escalate now';}else if(days<=14){severity='CRITICAL';action='Escalate to VP Compliance + outside counsel';}else if(days<=30){severity='URGENT';action='Owner must confirm progress this week';}else if(days<=60){severity='WARNING';action='Owner confirm timeline';}else if(days<=90){severity='NOTICE';action='Add to next compliance committee agenda';}else continue;out.push({json:{...d,days_remaining:days,severity,action,alert_key:`${d.deadline_type}_${d.due_date}`}});}return out;"
      }
    },
    {
      "id": "4",
      "name": "Route by Severity",
      "type": "n8n-nodes-base.switch",
      "parameters": {
        "dataType": "string",
        "value1": "={{$json.severity}}",
        "rules": {
          "rules": [
            {
              "value2": "OVERDUE"
            },
            {
              "value2": "CRITICAL"
            },
            {
              "value2": "URGENT"
            },
            {
              "value2": "WARNING"
            }
          ]
        }
      }
    },
    {
      "id": "5",
      "name": "Slack #compliance OVERDUE",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "#compliance",
        "text": "={{`:red_circle: OVERDUE: ${$json.deadline_type} was due ${Math.abs($json.days_remaining)} days ago. Owner: ${$json.owner}. Action: ${$json.action}`}}"
      }
    },
    {
      "id": "6",
      "name": "Email VP Compliance CRITICAL",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "operation": "send",
        "toEmail": "={{$json.owner_email}}",
        "ccEmail": "vp-compliance@yourplatform.com",
        "subject": "=[CRITICAL] ={{$json.deadline_type}} due in {{$json.days_remaining}} days",
        "message": "={{`${$json.deadline_type} is due in ${$json.days_remaining} days (${$json.due_date}).\\n\\nRegulatory note: ${$json.regulation_citation}\\nRequired action: ${$json.action}\\n\\nThis item requires VP Compliance sign-off.`}}"
      }
    },
    {
      "id": "7",
      "name": "Slack #compliance URGENT",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "#compliance",
        "text": "={{`:large_yellow_circle: URGENT: ${$json.deadline_type} in ${$json.days_remaining} days. Owner: ${$json.owner}. ${$json.action}`}}"
      }
    },
    {
      "id": "8",
      "name": "Slack #compliance WARNING",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "#compliance",
        "text": "={{`:large_blue_circle: WARNING: ${$json.deadline_type} in ${$json.days_remaining} days. Owner: ${$json.owner}. ${$json.action}`}}"
      }
    }
  ],
  "connections": {
    "Weekdays 8 AM": {
      "main": [
        [
          {
            "node": "Load Deadlines"
          }
        ]
      ]
    },
    "Load Deadlines": {
      "main": [
        [
          {
            "node": "Calculate Urgency"
          }
        ]
      ]
    },
    "Calculate Urgency": {
      "main": [
        [
          {
            "node": "Route by Severity"
          }
        ]
      ]
    },
    "Route by Severity": {
      "main": [
        [
          {
            "node": "Slack #compliance OVERDUE"
          }
        ],
        [
          {
            "node": "Email VP Compliance CRITICAL"
          }
        ],
        [
          {
            "node": "Slack #compliance URGENT"
          }
        ],
        [
          {
            "node": "Slack #compliance WARNING"
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

4. Customer Complaint & FINRA Rule 4530 Notification Pipeline

FINRA Rule 4530 requires member firms to report customer complaints within 30 calendar days of the quarter in which they're received — and specific events (arbitration, regulatory action) within 30 days of the event. Most platforms miss this clock because complaints arrive in support tickets, not compliance inboxes.

8 incident types with response windows:

Incident Regulation Clock
FINRA_4530_CUSTOMER_COMPLAINT FINRA Rule 4530(a)(1) 30 days post quarter-end
SEC_MARKETING_RULE_VIOLATION 17 CFR §275.206(4)-1 Remove immediately; document
ERISA_FIDUCIARY_BREACH_ALLEGATION ERISA §404 + DOL Notify DOL if self-dealing
SEC_BOOKS_RECORDS_FAILURE SEC Rule 204-2 Immediate — remediate + document
FINRA_ARBITRATION_INITIATED FINRA Rule 4530(a)(3) 30 days of notice
DATA_BREACH_INVESTOR_PII SEC Reg S-P / state breach laws 30–72h depending on state
DOL_PROHIBITED_TRANSACTION ERISA §406 / DOL PTE File Form 5330; notify participants
FINRA_REGULATORY_INVESTIGATION FINRA Rule 4530(a)(5) 30 days of notice
{
  "name": "WealthTech Incident & FINRA 4530 Pipeline",
  "nodes": [
    {
      "id": "1",
      "name": "Incident Webhook",
      "type": "n8n-nodes-base.webhook",
      "parameters": {
        "path": "wealthtech-incident",
        "method": "POST"
      }
    },
    {
      "id": "2",
      "name": "Classify & Set Deadlines",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const d=items[0].json;const clockMap={FINRA_4530_CUSTOMER_COMPLAINT:{hours:null,note:'Queue for 30-day post-quarter FINRA 4530 report',channel:'#compliance-urgent',escalate:'General Counsel + CCO'},SEC_MARKETING_RULE_VIOLATION:{hours:1,note:'Remove ad/content immediately. Document in marketing archive.',channel:'#compliance-urgent',escalate:'CCO + Marketing'},ERISA_FIDUCIARY_BREACH_ALLEGATION:{hours:24,note:'ERISA \u00a7404 \u2014 if self-dealing, notify DOL. Retain outside ERISA counsel.',channel:'#compliance-critical',escalate:'CCO + Outside ERISA Counsel'},SEC_BOOKS_RECORDS_FAILURE:{hours:2,note:'SEC Rule 204-2 \u2014 document failure, initiate remediation, prepare examination response.',channel:'#compliance-critical',escalate:'CCO + IT + outside counsel'},FINRA_ARBITRATION_INITIATED:{hours:48,note:'FINRA Rule 4530(a)(3) \u2014 30-day reporting clock starts now.',channel:'#compliance-urgent',escalate:'CCO + Legal'},DATA_BREACH_INVESTOR_PII:{hours:24,note:'SEC Reg S-P + state breach laws (30-72h notification depending on state). Engage breach counsel.',channel:'#compliance-critical',escalate:'CCO + CISO + outside counsel'},DOL_PROHIBITED_TRANSACTION:{hours:72,note:'ERISA \u00a7406 \u2014 file Form 5330. Notify plan participants within DOL-prescribed window.',channel:'#compliance-critical',escalate:'CCO + ERISA Counsel'},FINRA_REGULATORY_INVESTIGATION:{hours:48,note:'FINRA Rule 4530(a)(5) \u2014 30-day reporting. Do not destroy records.',channel:'#compliance-critical',escalate:'CCO + Outside Regulatory Counsel'}};const cfg=clockMap[d.incident_type]||{hours:24,note:'Unknown incident type.',channel:'#compliance-urgent',escalate:'CCO'};const deadline_ts=cfg.hours?new Date(Date.now()+cfg.hours*3600000).toISOString():null;return [{json:{...d,response_hours:cfg.hours,regulatory_note:cfg.note,alert_channel:cfg.channel,escalate_to:cfg.escalate,deadline_ts,logged_ts:new Date().toISOString()}}];"
      }
    },
    {
      "id": "3",
      "name": "Slack Compliance Alert",
      "type": "n8n-nodes-base.slack",
      "parameters": {
        "channel": "={{$json.alert_channel}}",
        "text": "={{`:rotating_light: ${$json.incident_type}\\nClient: ${$json.client_name||'N/A'} | Account: ${$json.account_id||'N/A'}\\nEscalate to: ${$json.escalate_to}\\nRegulatory note: ${$json.regulatory_note}\\n${$json.deadline_ts?'Response deadline: '+$json.deadline_ts:''}`}}"
      }
    },
    {
      "id": "4",
      "name": "Log Incident",
      "type": "n8n-nodes-base.googleSheets",
      "parameters": {
        "operation": "appendOrUpdate",
        "sheetId": "YOUR_SHEET_ID",
        "range": "Incidents!A:I"
      }
    },
    {
      "id": "5",
      "name": "Email CCO",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "operation": "send",
        "toEmail": "cco@yourplatform.com",
        "subject": "=[INCIDENT] ={{$json.incident_type}} \u2014 {{$json.client_name||'Unknown'}}",
        "message": "={{`Incident Type: ${$json.incident_type}\\nClient: ${$json.client_name||'N/A'}\\nAccount: ${$json.account_id||'N/A'}\\nDescription: ${$json.description||'N/A'}\\n\\nRegulatory Note: ${$json.regulatory_note}\\nEscalate to: ${$json.escalate_to}\\n${$json.deadline_ts?'Response deadline: '+$json.deadline_ts:'No hard clock \u2014 queue for quarterly FINRA report.'}\\n\\nLogged: ${$json.logged_ts}`}"
      }
    }
  ],
  "connections": {
    "Incident Webhook": {
      "main": [
        [
          {
            "node": "Classify & Set Deadlines"
          }
        ]
      ]
    },
    "Classify & Set Deadlines": {
      "main": [
        [
          {
            "node": "Slack Compliance Alert"
          }
        ]
      ]
    },
    "Slack Compliance Alert": {
      "main": [
        [
          {
            "node": "Log Incident"
          }
        ]
      ]
    },
    "Log Incident": {
      "main": [
        [
          {
            "node": "Email CCO"
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

5. Weekly WealthTech Platform KPI Dashboard

Every Monday at 8 AM. Pulls from your platform DB — active RIA accounts, AUM under management, compliance incidents open, API call volume — and emails the CEO with CCO BCC.

{
  "name": "WealthTech Weekly KPI Dashboard",
  "nodes": [
    {
      "id": "1",
      "name": "Monday 8 AM",
      "type": "n8n-nodes-base.scheduleTrigger",
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1"
            }
          ]
        }
      }
    },
    {
      "id": "2",
      "name": "Query Platform Metrics",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT COUNT(*) FILTER (WHERE status='active') AS active_ria_accounts, COUNT(*) FILTER (WHERE status='active' AND tier='LARGE_RIA_ENTERPRISE') AS enterprise_accounts, COUNT(*) FILTER (WHERE created_at >= NOW()-INTERVAL '7 days') AS new_signups_7d, SUM(aum_usd) FILTER (WHERE status='active') AS total_aum_usd, SUM(mrr_usd) FILTER (WHERE status='active') AS mrr_usd FROM ria_accounts;"
      }
    },
    {
      "id": "3",
      "name": "Query Compliance Metrics",
      "type": "n8n-nodes-base.postgres",
      "parameters": {
        "operation": "executeQuery",
        "query": "SELECT COUNT(*) FILTER (WHERE status='OPEN' AND incident_type LIKE 'FINRA%') AS finra_open, COUNT(*) FILTER (WHERE status='OPEN' AND incident_type LIKE 'SEC%') AS sec_open, COUNT(*) FILTER (WHERE status='OPEN' AND incident_type LIKE 'ERISA%') AS erisa_open, COUNT(*) FILTER (WHERE status='OPEN' AND incident_type LIKE 'DOL%') AS dol_open, COUNT(*) FILTER (WHERE logged_ts >= NOW()-INTERVAL '7 days') AS new_incidents_7d FROM wealthtech_incidents;"
      }
    },
    {
      "id": "4",
      "name": "Merge Metrics",
      "type": "n8n-nodes-base.merge",
      "parameters": {
        "mode": "combine",
        "combinationMode": "multiplex"
      }
    },
    {
      "id": "5",
      "name": "Build HTML Report",
      "type": "n8n-nodes-base.code",
      "parameters": {
        "jsCode": "const p=items[0].json;const c=items[1]?.json||{};const prev=$getWorkflowStaticData('global');const mrrWoW=prev.last_mrr?((p.mrr_usd-prev.last_mrr)/prev.last_mrr*100).toFixed(1):'N/A';const aumWoW=prev.last_aum?((p.total_aum_usd-prev.last_aum)/prev.last_aum*100).toFixed(1):'N/A';$setWorkflowStaticData('global',{last_mrr:p.mrr_usd,last_aum:p.total_aum_usd});const totalOpen=(c.finra_open||0)+(c.sec_open||0)+(c.erisa_open||0)+(c.dol_open||0);const html=`<h2>WealthTech KPI \u2014 ${new Date().toISOString().slice(0,10)}</h2><table border='1' cellpadding='6'><tr><th>Metric</th><th>Value</th><th>WoW</th></tr><tr><td>Active RIA Accounts</td><td>${p.active_ria_accounts}</td><td>-</td></tr><tr><td>Enterprise Accounts</td><td>${p.enterprise_accounts}</td><td>-</td></tr><tr><td>New Signups (7d)</td><td>${p.new_signups_7d}</td><td>-</td></tr><tr><td>Total AUM (USD)</td><td>$${Number(p.total_aum_usd||0).toLocaleString()}</td><td>${aumWoW}%</td></tr><tr><td>MRR (USD)</td><td>$${Number(p.mrr_usd||0).toLocaleString()}</td><td>${mrrWoW}%</td></tr><tr><td colspan='3'><b>Compliance</b></td></tr><tr><td>FINRA Open</td><td>${c.finra_open||0}</td><td>-</td></tr><tr><td>SEC Open</td><td>${c.sec_open||0}</td><td>-</td></tr><tr><td>ERISA/DOL Open</td><td>${(c.erisa_open||0)+(c.dol_open||0)}</td><td>-</td></tr><tr><td>New Incidents (7d)</td><td>${c.new_incidents_7d||0}</td><td>-</td></tr></table>${totalOpen>5?'<p style=color:red><b>ACTION: '+totalOpen+' open compliance incidents \u2014 review before week-end.</b></p>':''}`;return [{json:{html,total_open:totalOpen}}];"
      }
    },
    {
      "id": "6",
      "name": "Email CEO + CCO BCC",
      "type": "n8n-nodes-base.gmail",
      "parameters": {
        "operation": "send",
        "toEmail": "ceo@yourplatform.com",
        "bccEmail": "cco@yourplatform.com",
        "subject": "WealthTech Weekly KPI \u2014 ={{new Date().toISOString().slice(0,10)}}",
        "message": "={{$json.html}}",
        "messageType": "html"
      }
    }
  ],
  "connections": {
    "Monday 8 AM": {
      "main": [
        [
          {
            "node": "Query Platform Metrics"
          }
        ]
      ]
    },
    "Query Platform Metrics": {
      "main": [
        [
          {
            "node": "Query Compliance Metrics"
          }
        ]
      ]
    },
    "Query Compliance Metrics": {
      "main": [
        [
          {
            "node": "Merge Metrics"
          }
        ]
      ]
    },
    "Merge Metrics": {
      "main": [
        [
          {
            "node": "Build HTML Report"
          }
        ]
      ]
    },
    "Build HTML Report": {
      "main": [
        [
          {
            "node": "Email CEO + CCO BCC"
          }
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Why self-hosted n8n for WealthTech/RIA SaaS?

Concern Zapier/Make Self-hosted n8n
SEC Rule 204-2 Books & Records Client data transits cloud iPaaS — not in your ADV Records stay in your compliance boundary
FINRA 4530 complaint routing Third-party processor — may not appear in FINRA exam response Full audit log in your Postgres
ERISA §404 fiduciary data Portfolio/advice data egresses to cloud Stays on-prem or in your cloud VPC
DOL prohibited transaction evidence Third-party audit trail — chain of custody questions Git-versioned workflow = immutable evidence
SOC2 CC9.2 vendor risk Zapier/Make added to vendor inventory n8n is yours — no added vendor
Enterprise procurement 'We use Zapier for compliance workflows' = RFP disqualifier 'Self-hosted n8n, no data egress' = differentiator

5 questions WealthTech buyers ask

Q: Does n8n store our client AUM/portfolio data?
A: Only what you configure. With self-hosted n8n, all data stays in your infrastructure — nothing goes to n8n's servers.

Q: Can we use this as Books & Records evidence in an SEC examination?
A: n8n workflow execution logs are stored in your own database. Combined with git-versioned workflow code, they provide an immutable audit trail.

Q: How do we handle the FINRA 4530 quarterly reporting window?
A: Workflow 4 above queues every FINRA_4530_CUSTOMER_COMPLAINT event with a timestamp. Export the Sheets log at quarter-end — your 4530 report is pre-populated.

Q: Is this compliant with DOL PTE 2020-02 fiduciary documentation requirements?
A: PTE 2020-02 §V(b) requires written documentation of the specific basis for each investment recommendation. n8n can automate the generation and storage of that documentation — but legal review of your specific implementation is required.

Q: What about ERISA §406 prohibited transaction monitoring?
A: Workflow 4 includes a DOL_PROHIBITED_TRANSACTION incident type. Wire it to your transaction monitoring system for real-time alerts.


All 5 workflows are import-ready JSON. Copy, paste into n8n, connect your data sources.

If your platform needs ready-made n8n templates for automation beyond compliance — customer onboarding, reporting, and data pipelines — the FlowKit template library has 15 production-ready workflows from $12.

Top comments (0)