If you run a WealthTech or investment SaaS platform in 2026, you're navigating a compliance maze that spans US, EU, and global regulators simultaneously.
SEC Regulation Best Interest (17 CFR 240.15l-1) requires broker-dealers to act in retail customers' best interest and deliver Form CRS at or before account opening. FINRA Rule 4511 mandates six-year books-and-records retention with the first two years in an easily accessible place. MiFID II RTS 28 requires annual best execution reports published by April 30 each year. CFTC 17 CFR §1.35 demands five-year trading records for commodity advisors. FinCEN BSA rules require Currency Transaction Reports within 15 days for transactions over $10,000 and Suspicious Activity Reports within 30 days of detecting suspicious activity.
Miss any of these and you're looking at SEC enforcement actions, FINRA fines of $10,000+ per violation, or FinCEN penalties that can reach $1 million per day. The clock starts the moment a customer opens an account — or a transaction clears.
Here are 5 production-ready n8n workflows that automate the most time-sensitive compliance obligations for WealthTech SaaS vendors.
The Compliance Stack This Covers
| Regulation | Obligation | Deadline |
|---|---|---|
| SEC Reg BI 17 CFR 240.15l-1 | Form CRS delivery | At or before account opening |
| FINRA Rule 4511 | Books & records retention | 6 years (2yr accessible) |
| FINRA Rule 4370 | Business continuity plan | Annual review |
| Dodd-Frank §913 | Best interest standard | Ongoing |
| MiFID II RTS 28 | Best execution annual report | By April 30 each year |
| CFTC 17 CFR §1.35 | Trading record retention | 5 years |
| FinCEN BSA 31 CFR §1010.311 | Currency Transaction Reports | Within 15 days |
| FinCEN BSA 31 CFR §1020.320 | Suspicious Activity Reports | Within 30 days |
| GDPR Art.9 | Special category financial data | Explicit consent required |
| SEC Regulation S-P | Privacy notice | At account opening + annual |
Workflow 1: Tier-Segmented Compliance Onboarding Drip
Different WealthTech tiers face different Day 1 obligations. A robo-advisor must deliver Form CRS immediately. A crypto platform triggers FinCEN CIP/KYC requirements. This workflow routes new customers to the right compliance email based on their tier.
Tiers handled:
-
ROBO_ADVISOR_SAAS→ SEC Reg BI Form CRS delivery notice -
PORTFOLIO_MANAGEMENT_SAAS→ FINRA Rule 4511 six-year records notice -
TRADING_ANALYTICS_SAAS→ CFTC Rule 1.35 five-year retention notice -
CRYPTO_ASSET_SAAS→ FinCEN BSA CIP/KYC 30-day verification notice
{
"name": "Tier-Segmented Onboarding Drip",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 9 * * *"
}
]
}
},
"name": "Schedule Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
250,
300
],
"id": "sched-1"
},
{
"parameters": {
"url": "https://api.example.com/customers/new-today",
"options": {}
},
"name": "Fetch New Customers",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4.1,
"position": [
450,
300
],
"id": "fetch-1"
},
{
"parameters": {
"jsCode": "return $input.all().flatMap(item => (item.json.customers || []).map(c => ({json: c})));"
},
"name": "Flatten Customers",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
650,
300
],
"id": "code-1"
},
{
"parameters": {
"rules": {
"rules": [
{
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.customer_tier }}",
"rightValue": "ROBO_ADVISOR_SAAS",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "RoboAdvisor"
},
{
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.customer_tier }}",
"rightValue": "PORTFOLIO_MANAGEMENT_SAAS",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Portfolio"
},
{
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.customer_tier }}",
"rightValue": "TRADING_ANALYTICS_SAAS",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Trading"
},
{
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.customer_tier }}",
"rightValue": "CRYPTO_ASSET_SAAS",
"operator": {
"type": "string",
"operation": "equals"
}
}
]
},
"renameOutput": true,
"outputKey": "Crypto"
}
]
},
"fallbackOutput": "extra"
},
"name": "Switch on Tier",
"type": "n8n-nodes-base.switch",
"typeVersion": 3,
"position": [
850,
300
],
"id": "switch-1"
},
{
"parameters": {
"fromEmail": "compliance@flowkit.ai",
"toEmail": "={{ $json.email }}",
"subject": "SEC Reg BI Day 1: Your Form CRS Delivery Obligation Starts Now",
"text": "Welcome to the platform. Under SEC Regulation Best Interest (17 CFR 240.15l-1), your Form CRS must be delivered at or before the time of opening a new retail account. Your 30-day Form CRS delivery log has started. Contact compliance@flowkit.ai with questions."
},
"name": "Email RoboAdvisor",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
1100,
100
],
"id": "email-1"
},
{
"parameters": {
"fromEmail": "compliance@flowkit.ai",
"toEmail": "={{ $json.email }}",
"subject": "FINRA Rule 4511 Day 1: 6-Year Books & Records Clock Started",
"text": "Welcome. FINRA Rule 4511 requires broker-dealers to preserve all records for at least 6 years, with the first 2 years in an easily accessible place. Your FINRA record retention compliance clock has started for this account."
},
"name": "Email Portfolio",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
1100,
250
],
"id": "email-2"
},
{
"parameters": {
"fromEmail": "compliance@flowkit.ai",
"toEmail": "={{ $json.email }}",
"subject": "CFTC Rule 1.35 Day 1: 5-Year Trading Record Retention Starts Now",
"text": "Welcome. CFTC Regulation 17 CFR \u00a71.35 requires commodity trading advisors to keep all trading records for a minimum of 5 years. Your retention clock has started."
},
"name": "Email Trading",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
1100,
400
],
"id": "email-3"
},
{
"parameters": {
"fromEmail": "compliance@flowkit.ai",
"toEmail": "={{ $json.email }}",
"subject": "FinCEN BSA Day 1: CIP/KYC Verification Required Within 30 Days",
"text": "Welcome. Under the Bank Secrecy Act and FinCEN Customer Identification Program rules, identity verification must be completed within 30 days of account opening. Please complete your KYC verification to avoid account restrictions."
},
"name": "Email Crypto",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
1100,
550
],
"id": "email-4"
}
],
"connections": {
"Schedule Trigger": {
"main": [
[
{
"node": "Fetch New Customers",
"type": "main",
"index": 0
}
]
]
},
"Fetch New Customers": {
"main": [
[
{
"node": "Flatten Customers",
"type": "main",
"index": 0
}
]
]
},
"Flatten Customers": {
"main": [
[
{
"node": "Switch on Tier",
"type": "main",
"index": 0
}
]
]
},
"Switch on Tier": {
"main": [
[
{
"node": "Email RoboAdvisor",
"type": "main",
"index": 0
}
],
[
{
"node": "Email Portfolio",
"type": "main",
"index": 0
}
],
[
{
"node": "Email Trading",
"type": "main",
"index": 0
}
],
[
{
"node": "Email Crypto",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 2: SEC Reg BI / FINRA / CFTC Compliance Deadline Tracker
Twelve compliance deadline types, weekday morning monitoring, urgency classification, and dual Slack + email escalation for CRITICAL/OVERDUE items. This is the core clock-watching engine.
Deadline types tracked:
-
FORM_CRS_DELIVERY— at or before account opening (SEC Reg BI) -
FINRA_RECORDS_6YR— six-year books-and-records retention (FINRA 4511) -
CFTC_RECORDS_5YR— five-year trading records (CFTC §1.35) -
FINCEN_CTR_15DAY— Currency Transaction Report within 15 days -
FINCEN_SAR_30DAY— Suspicious Activity Report within 30 days -
MIFID_RTS28_ANNUAL— best execution report by April 30 -
GDPR_CONSENT_RENEWAL— annual consent refresh for Art.9 data -
SEC_REG_SP_PRIVACY_NOTICE— annual privacy notice (Regulation S-P) -
FINRA_4370_BCP_ANNUAL— Business Continuity Plan annual review -
OFAC_SANCTIONS_SCREEN— OFAC SDN list re-screening (best practice: monthly) -
CIP_KYC_30DAY— FinCEN CIP identity verification within 30 days -
RECORD_RETENTION_EXPIRY— upcoming record destruction eligibility review
{
"name": "SEC Reg BI / FINRA / CFTC Compliance Deadline Tracker",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1-5"
}
]
}
},
"name": "Weekday 8AM Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
250,
300
],
"id": "sched-2"
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT d.id, d.entity_id, d.deadline_type, d.due_date, d.status, e.name, e.tier, e.email FROM compliance_deadlines d JOIN entities e ON d.entity_id = e.id WHERE d.due_date <= NOW() + INTERVAL '30 days' AND d.status NOT IN ('COMPLETED','WAIVED') ORDER BY d.due_date ASC LIMIT 200"
},
"name": "Query Deadlines",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
450,
300
],
"id": "pg-1"
},
{
"parameters": {
"jsCode": "const items = $input.all();\nconst urgency = items.map(item => {\n const d = item.json;\n const due = new Date(d.due_date);\n const now = new Date();\n const days = Math.ceil((due - now) / 86400000);\n let level = 'NORMAL';\n if (days < 0) level = 'OVERDUE';\n else if (days <= 3) level = 'CRITICAL';\n else if (days <= 7) level = 'HIGH';\n else if (days <= 14) level = 'MEDIUM';\n return { json: { ...d, days_until_due: days, urgency_level: level } };\n});\nreturn urgency;"
},
"name": "Classify Urgency",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
650,
300
],
"id": "code-2"
},
{
"parameters": {
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.urgency_level }}",
"rightValue": "NORMAL",
"operator": {
"type": "string",
"operation": "notEquals"
}
}
]
}
},
"name": "Filter Actionable",
"type": "n8n-nodes-base.filter",
"typeVersion": 2,
"position": [
850,
300
],
"id": "filter-1"
},
{
"parameters": {
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.urgency_level }}",
"rightValue": "NORMAL",
"operator": {
"type": "string",
"operation": "notEquals"
}
},
{
"leftValue": "={{ ['OVERDUE','CRITICAL'].includes($json.urgency_level) }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "equals"
}
}
]
}
},
"name": "Critical/Overdue Branch",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1050,
300
],
"id": "if-1"
},
{
"parameters": {
"resource": "message",
"channel": "#compliance-critical",
"text": "={{ ':rotating_light: ' + $json.urgency_level + ' \u2014 ' + $json.deadline_type + ' for ' + $json.name + ' (' + $json.tier + ') due ' + $json.due_date + ' (' + $json.days_until_due + ' days). Escalate immediately.' }}"
},
"name": "Slack Critical",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.1,
"position": [
1300,
200
],
"id": "slack-1"
},
{
"parameters": {
"fromEmail": "compliance@flowkit.ai",
"toEmail": "={{ $json.email }}",
"subject": "={{ 'COMPLIANCE ALERT: ' + $json.deadline_type + ' deadline in ' + $json.days_until_due + ' days' }}",
"text": "={{ 'This is an automated compliance alert. Deadline: ' + $json.deadline_type + '. Due: ' + $json.due_date + '. Status: ' + $json.urgency_level + '. Immediate action required.' }}"
},
"name": "Email Alert",
"type": "n8n-nodes-base.emailSend",
"typeVersion": 2,
"position": [
1300,
350
],
"id": "email-5"
},
{
"parameters": {
"resource": "message",
"channel": "#compliance-queue",
"text": "={{ ':calendar: ' + $json.deadline_type + ' \u2014 ' + $json.name + ' due ' + $json.due_date + ' (' + $json.days_until_due + ' days, ' + $json.urgency_level + ')' }}"
},
"name": "Slack Queue",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.1,
"position": [
1300,
500
],
"id": "slack-2"
}
],
"connections": {
"Weekday 8AM Trigger": {
"main": [
[
{
"node": "Query Deadlines",
"type": "main",
"index": 0
}
]
]
},
"Query Deadlines": {
"main": [
[
{
"node": "Classify Urgency",
"type": "main",
"index": 0
}
]
]
},
"Classify Urgency": {
"main": [
[
{
"node": "Filter Actionable",
"type": "main",
"index": 0
}
]
]
},
"Filter Actionable": {
"main": [
[
{
"node": "Critical/Overdue Branch",
"type": "main",
"index": 0
}
]
]
},
"Critical/Overdue Branch": {
"main": [
[
{
"node": "Slack Critical",
"type": "main",
"index": 0
},
{
"node": "Email Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Slack Queue",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 3: FinCEN BSA / AML Transaction Monitor (5-Minute Polling)
Runs every 5 minutes. Flags Currency Transaction Report obligations ($10K+), OFAC high-risk country exposure, structuring patterns, and SAR review triggers. Inserts flagged transactions into a review queue and fires Slack alerts.
AML flags generated:
-
CTR_REQUIRED_31_CFR_1010_311— transaction ≥ $10,000 -
OFAC_HIGH_RISK_COUNTRY— transaction involving OFAC-sanctioned jurisdiction -
STRUCTURING_SUSPICIOUS_31_CFR_1010_314— transaction $9,000–$9,999 (structuring pattern) -
SAR_REVIEW_31_CFR_1020_320— $5,000+ with other risk flags = SAR review required
{
"name": "FinCEN BSA / AML Transaction Monitor",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "*/5 * * * *"
}
]
}
},
"name": "5-Min Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
250,
300
],
"id": "sched-3"
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT t.id, t.account_id, t.amount_usd, t.transaction_type, t.country_code, t.created_at, a.customer_name, a.tier FROM transactions t JOIN accounts a ON t.account_id = a.id WHERE t.created_at >= NOW() - INTERVAL '5 minutes' ORDER BY t.amount_usd DESC"
},
"name": "Query Recent Transactions",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
450,
300
],
"id": "pg-2"
},
{
"parameters": {
"jsCode": "const items = $input.all();\nreturn items.map(item => {\n const t = item.json;\n const flags = [];\n if (t.amount_usd >= 10000) flags.push('CTR_REQUIRED_31_CFR_1010_311');\n if (t.amount_usd >= 5000 && ['SD', 'DO', 'IR', 'KP', 'CU', 'SY'].includes(t.country_code)) flags.push('OFAC_HIGH_RISK_COUNTRY');\n if (t.transaction_type === 'STRUCTURED' && t.amount_usd < 10000 && t.amount_usd > 9000) flags.push('STRUCTURING_SUSPICIOUS_31_CFR_1010_314');\n if (t.amount_usd >= 5000 && flags.length > 0) flags.push('SAR_REVIEW_31_CFR_1020_320');\n return { json: { ...t, aml_flags: flags, requires_action: flags.length > 0 } };\n})"
},
"name": "AML Flag Engine",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
650,
300
],
"id": "code-3"
},
{
"parameters": {
"conditions": {
"conditions": [
{
"leftValue": "={{ $json.requires_action }}",
"rightValue": true,
"operator": {
"type": "boolean",
"operation": "equals"
}
}
]
}
},
"name": "Filter Flagged",
"type": "n8n-nodes-base.filter",
"typeVersion": 2,
"position": [
850,
300
],
"id": "filter-2"
},
{
"parameters": {
"operation": "insert",
"table": "aml_review_queue",
"columns": "transaction_id,account_id,amount_usd,flags,detected_at,status",
"additionalFields": {}
},
"name": "Insert AML Queue",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
1050,
300
],
"id": "pg-3"
},
{
"parameters": {
"resource": "message",
"channel": "#aml-alerts",
"text": "={{ ':money_with_wings: AML FLAG \u2014 ' + $json.aml_flags.join(', ') + ' | Customer: ' + $json.customer_name + ' | Amount: $' + $json.amount_usd + ' | TxID: ' + $json.id }}"
},
"name": "Slack AML Alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.1,
"position": [
1300,
300
],
"id": "slack-3"
}
],
"connections": {
"5-Min Trigger": {
"main": [
[
{
"node": "Query Recent Transactions",
"type": "main",
"index": 0
}
]
]
},
"Query Recent Transactions": {
"main": [
[
{
"node": "AML Flag Engine",
"type": "main",
"index": 0
}
]
]
},
"AML Flag Engine": {
"main": [
[
{
"node": "Filter Flagged",
"type": "main",
"index": 0
}
]
]
},
"Filter Flagged": {
"main": [
[
{
"node": "Insert AML Queue",
"type": "main",
"index": 0
}
]
]
},
"Insert AML Queue": {
"main": [
[
{
"node": "Slack AML Alert",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 4: MiFID II RTS 28 Best Execution Annual Report Generator
Fires January 1 each year. Queries all execution venues by asset class, calculates slippage and fill rate, ranks top 5 venues per class, and generates the RTS 28 disclosure report. Stores in Postgres and alerts compliance team to publish before April 30.
What RTS 28 requires:
- Top 5 execution venues per asset class by trading volume
- Quality of execution metrics (fill rate, price improvement/slippage)
- Published on the firm's website by April 30 each year
- Applies to investment firms executing orders on behalf of clients under MiFID II
{
"name": "MiFID II RTS 28 Best Execution Annual Report Generator",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 6 1 1 *"
}
]
}
},
"name": "Annual Jan 1 Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
250,
300
],
"id": "sched-4"
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT venue_id, venue_name, asset_class, COUNT(*) as order_count, AVG(execution_price_vs_benchmark) as avg_slippage_bps, AVG(fill_rate_pct) as avg_fill_rate, SUM(notional_eur) as total_notional_eur, RANK() OVER (PARTITION BY asset_class ORDER BY COUNT(*) DESC) as venue_rank FROM executions WHERE executed_at >= DATE_TRUNC('year', NOW() - INTERVAL '1 year') AND executed_at < DATE_TRUNC('year', NOW()) GROUP BY venue_id, venue_name, asset_class ORDER BY asset_class, venue_rank"
},
"name": "Query RTS28 Data",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
450,
300
],
"id": "pg-4"
},
{
"parameters": {
"jsCode": "const items = $input.all();\nconst year = new Date().getFullYear() - 1;\nconst byClass = {};\nitems.forEach(item => {\n const d = item.json;\n if (!byClass[d.asset_class]) byClass[d.asset_class] = [];\n byClass[d.asset_class].push(d);\n});\nconst report = {\n report_year: year,\n generated_at: new Date().toISOString(),\n mifid_ii_article: 'RTS 28 \u2014 Commission Delegated Regulation (EU) 2017/576',\n publication_deadline: year + 1 + '-04-30',\n asset_classes: byClass,\n top5_venues_per_class: Object.fromEntries(Object.entries(byClass).map(([cls, venues]) => [cls, venues.slice(0,5)]))\n};\nreturn [{ json: report }];"
},
"name": "Build RTS28 Report",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
650,
300
],
"id": "code-4"
},
{
"parameters": {
"operation": "insert",
"table": "mifid_rts28_reports",
"columns": "report_year,report_json,generated_at,status"
},
"name": "Store Report",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
850,
300
],
"id": "pg-5"
},
{
"parameters": {
"resource": "message",
"channel": "#compliance-reporting",
"text": "={{ ':bar_chart: MiFID II RTS 28 Best Execution Report generated for ' + $json.report_year + '. Publication deadline: ' + $json.publication_deadline + '. ' + Object.keys($json.asset_classes).length + ' asset classes. Review and publish before April 30.' }}"
},
"name": "Slack Report Ready",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.1,
"position": [
1100,
300
],
"id": "slack-4"
}
],
"connections": {
"Annual Jan 1 Trigger": {
"main": [
[
{
"node": "Query RTS28 Data",
"type": "main",
"index": 0
}
]
]
},
"Query RTS28 Data": {
"main": [
[
{
"node": "Build RTS28 Report",
"type": "main",
"index": 0
}
]
]
},
"Build RTS28 Report": {
"main": [
[
{
"node": "Store Report",
"type": "main",
"index": 0
}
]
]
},
"Store Report": {
"main": [
[
{
"node": "Slack Report Ready",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 5: Weekly WealthTech Compliance KPI Dashboard
Every Monday morning: new customers, overdue deadlines, AML flags, Form CRS deliveries, average SAR filing time, and records expiring in 30 days. One Slack message that tells you if the week needs firefighting.
KPIs tracked:
- New customers this week (Form CRS delivery obligation count)
- Overdue compliance deadlines (should be zero)
- AML flags filed this week vs. threshold
- Form CRS deliveries confirmed (Reg BI §240.15l-1(a)(2)(i))
- Average SAR filing time (FinCEN requires ≤ 30 days from detection)
- Records expiring within 30 days (retention schedule management)
{
"name": "Weekly WealthTech Compliance KPI Dashboard",
"nodes": [
{
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 7 * * 1"
}
]
}
},
"name": "Monday 7AM Trigger",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1.1,
"position": [
250,
300
],
"id": "sched-5"
},
{
"parameters": {
"operation": "executeQuery",
"query": "SELECT (SELECT COUNT(*) FROM customers WHERE created_at >= NOW() - INTERVAL '7 days') as new_customers_7d, (SELECT COUNT(*) FROM compliance_deadlines WHERE status = 'OVERDUE') as overdue_deadlines, (SELECT COUNT(*) FROM aml_review_queue WHERE status = 'PENDING' AND detected_at >= NOW() - INTERVAL '7 days') as aml_flags_7d, (SELECT COUNT(*) FROM form_crs_deliveries WHERE delivered_at >= NOW() - INTERVAL '7 days') as form_crs_delivered_7d, (SELECT ROUND(AVG(days_to_complete)) FROM sar_filings WHERE filed_at >= NOW() - INTERVAL '90 days') as avg_sar_days, (SELECT COUNT(*) FROM records WHERE retention_expires_at <= NOW() + INTERVAL '30 days') as records_expiring_30d"
},
"name": "KPI Query",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2.3,
"position": [
450,
300
],
"id": "pg-6"
},
{
"parameters": {
"jsCode": "const d = $input.first().json;\nconst kpis = [\n { metric: 'New Customers (7d)', value: d.new_customers_7d, benchmark: null },\n { metric: 'Overdue Compliance Deadlines', value: d.overdue_deadlines, alert: d.overdue_deadlines > 0 },\n { metric: 'AML Flags This Week', value: d.aml_flags_7d, alert: d.aml_flags_7d > 5 },\n { metric: 'Form CRS Deliveries (7d)', value: d.form_crs_delivered_7d, note: 'SEC Reg BI 17 CFR 240.15l-1' },\n { metric: 'Avg SAR Filing Days (90d)', value: d.avg_sar_days, benchmark: 30, alert: d.avg_sar_days > 30 },\n { metric: 'Records Expiring in 30d', value: d.records_expiring_30d, alert: d.records_expiring_30d > 0 }\n];\nconst text = kpis.map(k => (k.alert ? ':warning: ' : ':white_check_mark: ') + k.metric + ': ' + k.value + (k.note ? ' (' + k.note + ')' : '')).join('\\n');\nreturn [{ json: { kpis, slack_text: text } }];"
},
"name": "Format KPIs",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
650,
300
],
"id": "code-5"
},
{
"parameters": {
"resource": "message",
"channel": "#wealthtech-kpi",
"text": "={{ ':bank: WealthTech Weekly Compliance KPI \u2014 ' + new Date().toISOString().slice(0,10) + '\\n' + $json.slack_text }}"
},
"name": "Slack KPI Report",
"type": "n8n-nodes-base.slack",
"typeVersion": 2.1,
"position": [
900,
300
],
"id": "slack-5"
}
],
"connections": {
"Monday 7AM Trigger": {
"main": [
[
{
"node": "KPI Query",
"type": "main",
"index": 0
}
]
]
},
"KPI Query": {
"main": [
[
{
"node": "Format KPIs",
"type": "main",
"index": 0
}
]
]
},
"Format KPIs": {
"main": [
[
{
"node": "Slack KPI Report",
"type": "main",
"index": 0
}
]
]
}
}
}
Customer Tier Reference
| Tier Flag | Primary Regulatory Obligation |
|---|---|
ROBO_ADVISOR_SAAS |
SEC Reg BI Form CRS + Dodd-Frank §913 |
PORTFOLIO_MANAGEMENT_SAAS |
FINRA Rule 4511 + Regulation S-P |
TRADING_ANALYTICS_SAAS |
CFTC 17 CFR §1.35 + NFA recordkeeping |
WEALTH_CRM_SAAS |
FINRA 4511 + GDPR Art.9 special category |
ESG_INVESTMENT_SAAS |
MiFID II RTS 28 + SEC ESG disclosure |
CRYPTO_ASSET_SAAS |
FinCEN BSA CIP/KYC + OFAC SDN screening |
WEALTHTECH_STARTUP |
FinCEN CIP + SEC exemption monitoring |
Key Compliance Facts for WealthTech SaaS
SEC Regulation Best Interest (Reg BI): Effective June 30, 2020. Form CRS (Customer Relationship Summary) must be delivered to retail customers at or before the time of account opening. Broker-dealers must document how they satisfied the best interest obligation for each recommendation.
FINRA Rule 4511: Broker-dealer records must be retained for at least six years. Electronic records must be stored in a non-rewriteable, non-erasable format (WORM). The first two years must be in an easily accessible location. Violations are $10,000+ per infraction.
FinCEN Currency Transaction Reports (31 CFR §1010.311): Any cash transaction over $10,000 must be reported within 15 days. Structuring transactions to avoid the $10,000 threshold is a federal crime (31 U.S.C. §5324) regardless of whether the underlying activity is legal.
FinCEN Suspicious Activity Reports (31 CFR §1020.320): SAR must be filed within 30 days of initial detection of suspicious activity. SAR confidentiality is protected by law (31 U.S.C. §5318(g)(2)) — tipping off the subject is prohibited.
MiFID II RTS 28: Investment firms must publish the top 5 execution venues per asset class annually. The report covers price improvement, fill rate, and execution costs. Publication deadline is April 30 each year.
Get All 14 FlowKit Templates
These 5 workflows are part of the FlowKit n8n Automation Template Library — 14 production-ready templates for compliance-sensitive SaaS vendors.
Each template includes:
- Full workflow JSON (import directly into n8n)
- Tier-segmentation logic (handle enterprise vs. SMB vs. startup differently)
- Compliance deadline tracking with urgency buckets
- Real regulatory citations (not placeholder text)
Get the full library at stripeai.gumroad.com
Disclaimer
These workflows are provided as engineering starting points. They are not legal advice. Consult qualified securities counsel and compliance professionals before using in production for regulated activities.
Top comments (0)