If your company builds software sold to lenders, real estate brokerages, title companies, or property managers, you don't just help your customers stay compliant — you bear vendor-side compliance obligations yourself.
When your LOS software mishandles a TRID disclosure timing window, your HMDA data pipeline submits bad LAR data, or your AI screening tool produces a disparate impact pattern under the Fair Housing Act — your company is in the chain of liability.
This post covers 5 production-ready n8n workflows for PropTech SaaS vendors: companies building software sold into the real estate and mortgage stack. Free workflow JSON included for each.
Why vendor-side PropTech compliance is different
| Your product | Downstream obligation |
|---|---|
| Loan Origination Software (LOS) | TRID §1026.19(e) 3-day delivery accuracy; HMDA LAR data integrity |
| AI appraisal / credit scoring | Fair Housing Act disparate impact — your model, not just the lender's use of it |
| Title/closing platform | RESPA §8 — referral fee APIs baked into your product = kickback exposure |
| Property management SaaS | Fair Housing Act §804 — stale listing data + geographic filtering = unequal access |
| HMDA analytics vendor | FFIEC Regulation C — LAR accuracy obligation flows to data vendor |
The regulatory risk travels downstream through your API. If your platform processed the bad data or missed the disclosure window, your company is named in the CFPB examination.
Workflow 1: Real Estate Enterprise Customer Onboarding Drip
Problem: New customers at a national lender have different compliance exposure than a community credit union or regional brokerage. A generic onboarding email doesn't set up the right workflows — HMDA customers need LAR pipeline guidance on day 1, Fair Housing AI customers need disparate impact monitoring configured before go-live.
What it does: Segments new customers by type (NATIONAL_LENDER, REGIONAL_BANK, COMMUNITY_CU, REAL_ESTATE_BROKERAGE, PROPERTY_MGMT_CO, TITLE_COMPANY) and by compliance flags (HMDA_LAR, TRID_REGULATION_X, FAIR_HOUSING_DISPARATE_IMPACT, RESPA_SECTION_8). Sends tailored onboarding emails on Day 0, Day 3, and Day 7 with compliance-specific setup guides. CSM alert on Slack for enterprise accounts.
{
"id": "proptech-onboarding-drip-001",
"name": "PropTech SaaS \u2014 Real Estate Enterprise Onboarding Drip",
"nodes": [
{
"id": "n1",
"name": "GoogleSheets Trigger",
"type": "n8n-nodes-base.googleSheetsTrigger",
"typeVersion": 4,
"position": [
200,
300
],
"parameters": {
"sheetId": "YOUR_SHEET_ID",
"range": "Customers!A:Z",
"event": "rowAdded"
}
},
{
"id": "n2",
"name": "Segment Customer",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
420,
300
],
"parameters": {
"jsCode": "\nconst customer_type = $json.customer_type?.toUpperCase() || 'REAL_ESTATE_BROKERAGE';\nconst flags = [];\nif ($json.processes_hmda_data === 'true') flags.push('HMDA_LAR');\nif ($json.los_integration === 'true') flags.push('TRID_REGULATION_X');\nif ($json.ai_screening_tool === 'true') flags.push('FAIR_HOUSING_DISPARATE_IMPACT');\nif ($json.referral_api_enabled === 'true') flags.push('RESPA_SECTION_8');\nif ($json.processes_biometrics === 'true') flags.push('BIPA_STATE_LAW');\n\nconst segment_map = {\n NATIONAL_LENDER: { tier: 'enterprise', csm: true, welcome_subject: 'Your n8n onboarding \u2014 TRID & HMDA automation ready' },\n REGIONAL_BANK: { tier: 'enterprise', csm: true, welcome_subject: 'Your n8n onboarding \u2014 RESPA & Fair Housing compliance' },\n COMMUNITY_CU: { tier: 'mid', csm: false, welcome_subject: 'FlowKit PropTech onboarding \u2014 getting started' },\n REAL_ESTATE_BROKERAGE: { tier: 'mid', csm: false, welcome_subject: 'Your FlowKit setup \u2014 MLS & Fair Housing workflows' },\n PROPERTY_MGMT_CO: { tier: 'mid', csm: false, welcome_subject: 'FlowKit onboarding \u2014 property management automations' },\n TITLE_COMPANY: { tier: 'mid', csm: false, welcome_subject: 'FlowKit onboarding \u2014 TRID & settlement service compliance' }\n};\n\nconst seg = segment_map[customer_type] || segment_map['REAL_ESTATE_BROKERAGE'];\nreturn { ...$json, ...seg, compliance_flags: flags.join(','), customer_type };\n"
}
},
{
"id": "n3",
"name": "Gmail Day0 Welcome",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
640,
300
],
"parameters": {
"sendTo": "={{ $json.contact_email }}",
"subject": "={{ $json.welcome_subject }}",
"emailType": "html",
"message": "={{ '<h2>Welcome to FlowKit, ' + $json.company_name + '</h2><p>Your n8n automation environment is ready. ' + ($json.compliance_flags.includes('HMDA_LAR') ? '<strong>HMDA note:</strong> Your HMDA LAR submission workflows are pre-configured. See attached integration guide.</p>' : '') + ($json.compliance_flags.includes('FAIR_HOUSING_DISPARATE_IMPACT') ? '<p><strong>Fair Housing note:</strong> Your AI screening tool integration includes our disparate impact monitoring workflow.</p>' : '') + '<p>Book your onboarding call: <a href=\"https://cal.flowkitai.com\">Schedule here</a></p>' }}"
}
},
{
"id": "n4",
"name": "Log to Sheets",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
860,
300
],
"parameters": {
"operation": "append",
"sheetId": "YOUR_SHEET_ID",
"range": "OnboardingLog!A:H",
"columns": {
"mappingMode": "defineBelow",
"value": {
"company": "={{ $json.company_name }}",
"email": "={{ $json.contact_email }}",
"type": "={{ $json.customer_type }}",
"tier": "={{ $json.tier }}",
"flags": "={{ $json.compliance_flags }}",
"day0_sent": "={{ new Date().toISOString() }}",
"status": "ONBOARDING"
}
}
}
},
{
"id": "n5",
"name": "Wait 3 Days",
"type": "n8n-nodes-base.wait",
"typeVersion": 1,
"position": [
1080,
300
],
"parameters": {
"amount": 3,
"unit": "days"
}
},
{
"id": "n6",
"name": "Gmail Day3 Integration Guide",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
1300,
300
],
"parameters": {
"sendTo": "={{ $json.contact_email }}",
"subject": "Day 3: Your PropTech integration guide + compliance checklist",
"emailType": "html",
"message": "={{ '<p>Hi ' + $json.contact_name + ',</p><p>Here are your next steps:</p><ul>' + ($json.compliance_flags.includes('HMDA_LAR') ? '<li><strong>HMDA LAR:</strong> Connect your LAR data source \u2014 guide: docs.flowkitai.com/hmda</li>' : '') + ($json.compliance_flags.includes('TRID_REGULATION_X') ? '<li><strong>TRID:</strong> Configure your Loan Estimate delivery monitor \u2014 guide: docs.flowkitai.com/trid</li>' : '') + ($json.compliance_flags.includes('FAIR_HOUSING_DISPARATE_IMPACT') ? '<li><strong>Fair Housing:</strong> Enable your disparate impact alert workflow \u2014 guide: docs.flowkitai.com/fair-housing</li>' : '') + '<li>Join our PropTech Slack community: slack.flowkitai.com</li></ul>' }}"
}
},
{
"id": "n7",
"name": "Wait 4 Days",
"type": "n8n-nodes-base.wait",
"typeVersion": 1,
"position": [
1520,
300
],
"parameters": {
"amount": 4,
"unit": "days"
}
},
{
"id": "n8",
"name": "Gmail Day7 QBR Invite",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
1740,
300
],
"parameters": {
"sendTo": "={{ $json.contact_email }}",
"subject": "Week 1 check-in: Are your compliance workflows running?",
"emailType": "html",
"message": "={{ '<p>Hi ' + $json.contact_name + ',</p><p>Book your week 1 QBR with your CSM: <a href=\"https://cal.flowkitai.com/qbr\">Schedule</a></p><p>We will review: HMDA LAR pipeline status, Fair Housing monitoring coverage, TRID deadline tracker setup.</p>' }}"
}
}
],
"connections": {
"GoogleSheets Trigger": {
"main": [
[
{
"node": "Segment Customer",
"type": "main",
"index": 0
}
]
]
},
"Segment Customer": {
"main": [
[
{
"node": "Gmail Day0 Welcome",
"type": "main",
"index": 0
}
]
]
},
"Gmail Day0 Welcome": {
"main": [
[
{
"node": "Log to Sheets",
"type": "main",
"index": 0
}
]
]
},
"Log to Sheets": {
"main": [
[
{
"node": "Wait 3 Days",
"type": "main",
"index": 0
}
]
]
},
"Wait 3 Days": {
"main": [
[
{
"node": "Gmail Day3 Integration Guide",
"type": "main",
"index": 0
}
]
]
},
"Gmail Day3 Integration Guide": {
"main": [
[
{
"node": "Wait 4 Days",
"type": "main",
"index": 0
}
]
]
},
"Wait 4 Days": {
"main": [
[
{
"node": "Gmail Day7 QBR Invite",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 2: HMDA/TRID/Fair Housing API Integration Health Monitor
Problem: Your HMDA LAR submission API goes down at 11pm and nobody knows until the LAR file has gaps. Your Fair Housing compliance engine is offline and your AI model is serving unfiltered outputs into production. Your TRID Loan Estimate delivery API times out — the 3-business-day clock is running, your customer doesn't know, and CFPB will ask who owns the delivery failure.
What it does: Runs every 5 minutes. Pings each critical integration endpoint. Maps status to specific regulatory risk with citation. Routes DOWN/DEGRADED status to #integration-ops Slack with the exact regulation at risk so the on-call engineer understands the stakes — not just 'service down' but 'Fair Housing output filtering disabled, FHA 42 USC §3604/3605 disparate impact risk'.
{
"id": "proptech-api-health-monitor-002",
"name": "PropTech SaaS \u2014 HMDA/TRID/Fair Housing API Health Monitor",
"nodes": [
{
"id": "n1",
"name": "Every 5 Minutes",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
200,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "minutes",
"minutesInterval": 5
}
]
}
}
},
{
"id": "n2",
"name": "Load Integration Endpoints",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
420,
300
],
"parameters": {
"jsCode": "\nreturn [\n { name: 'HMDA LAR Submission API', url: 'https://api.hmda.cfpb.gov/health', regulatory_risk: 'HMDA LAR annual submission accuracy \u2014 down = LAR data gap risk', reg_citation: '12 CFR Part 1003 (Regulation C)' },\n { name: 'Fair Housing Compliance Engine', url: 'https://fh-api.internal/health', regulatory_risk: 'AI output filtering disabled \u2014 disparate impact risk under FHA 42 USC 3604/3605', reg_citation: 'FHA 42 USC \u00a73604, EEOC AI Guidance 2023' },\n { name: 'TRID Loan Estimate Delivery API', url: 'https://trid-delivery.internal/health', regulatory_risk: 'TRID 3-business-day delivery clock risk \u2014 Reg Z \u00a71026.19(e)(1)(iii)', reg_citation: 'TRID Regulation Z/X 12 CFR 1024/1026' },\n { name: 'CFPB Complaint Portal Sync', url: 'https://cfpb-sync.internal/health', regulatory_risk: 'CFPB complaint intake delayed \u2014 response SLA at risk', reg_citation: 'CFPB UDAP 12 USC \u00a75531' },\n { name: 'MLS Data Feed Connector', url: 'https://mls-feed.internal/health', regulatory_risk: 'Listing data stale \u2014 Fair Housing stale listing = potential Equal Access claim', reg_citation: 'HUD Fair Housing Act \u00a7804' },\n { name: 'RESPA Referral Audit API', url: 'https://respa-audit.internal/health', regulatory_risk: 'Referral fee pattern detection offline \u2014 RESPA Section 8 kickback exposure', reg_citation: 'RESPA 12 USC \u00a72607, 12 CFR Part 1024.14' }\n];\n"
}
},
{
"id": "n3",
"name": "Ping Each Endpoint",
"type": "n8n-nodes-base.httpRequest",
"typeVersion": 4,
"position": [
640,
300
],
"parameters": {
"url": "={{ $json.url }}",
"method": "GET",
"timeout": 8000,
"options": {
"response": {
"response": {
"responseFormat": "text"
}
}
}
}
},
{
"id": "n4",
"name": "Evaluate Status",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
860,
300
],
"parameters": {
"jsCode": "\nconst endpoint = $('Load Integration Endpoints').item.json;\nconst statusCode = $json.statusCode || 0;\nlet severity = 'OK';\nlet alert_needed = false;\nif (statusCode === 0 || statusCode >= 500) { severity = 'DOWN'; alert_needed = true; }\nelse if (statusCode >= 400) { severity = 'DEGRADED'; alert_needed = true; }\nreturn { ...endpoint, statusCode, severity, alert_needed, checked_at: new Date().toISOString() };\n"
}
},
{
"id": "n5",
"name": "Alert Needed?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
1080,
300
],
"parameters": {
"conditions": {
"options": {
"caseSensitive": false
},
"conditions": [
{
"leftValue": "={{ $json.alert_needed }}",
"operator": {
"type": "boolean",
"operation": "true"
}
}
]
}
}
},
{
"id": "n6",
"name": "Slack Alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [
1300,
200
],
"parameters": {
"channel": "#integration-ops",
"text": "={{ ':red_circle: [' + $json.severity + '] ' + $json.name + ' is ' + $json.severity + '\\nRegulatory risk: ' + $json.regulatory_risk + '\\nCitation: ' + $json.reg_citation + '\\nChecked: ' + $json.checked_at }}"
}
},
{
"id": "n7",
"name": "Log to Sheets",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
1300,
400
],
"parameters": {
"operation": "append",
"sheetId": "YOUR_SHEET_ID",
"range": "IntegrationHealth!A:G",
"columns": {
"mappingMode": "defineBelow",
"value": {
"endpoint": "={{ $json.name }}",
"status": "={{ $json.severity }}",
"http_code": "={{ $json.statusCode }}",
"regulatory_risk": "={{ $json.regulatory_risk }}",
"checked_at": "={{ $json.checked_at }}"
}
}
}
}
],
"connections": {
"Every 5 Minutes": {
"main": [
[
{
"node": "Load Integration Endpoints",
"type": "main",
"index": 0
}
]
]
},
"Load Integration Endpoints": {
"main": [
[
{
"node": "Ping Each Endpoint",
"type": "main",
"index": 0
}
]
]
},
"Ping Each Endpoint": {
"main": [
[
{
"node": "Evaluate Status",
"type": "main",
"index": 0
}
]
]
},
"Evaluate Status": {
"main": [
[
{
"node": "Alert Needed?",
"type": "main",
"index": 0
}
]
]
},
"Alert Needed?": {
"main": [
[
{
"node": "Slack Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Log to Sheets",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 3: RESPA/Fair Housing/TRID/HMDA Compliance Deadline Tracker
Problem: Your compliance calendar lives in someone's head. HMDA LAR annual submission (March 1), SOC2 audit, CFPB examination prep, ADA Title III accessibility audit, NMLSR license renewal — each has a different owner and a different consequence for missing it. A missed CFPB examination prep window becomes a $1M enforcement action.
What it does: Reads compliance deadlines from a Google Sheet. Runs every weekday at 8 AM. Calculates OVERDUE/CRITICAL (≤14d)/URGENT (≤30d)/WARNING (≤60d)/NOTICE (≤90d) tiers. Deduplicates (no repeat alert on the same day). Routes to #compliance-ops Slack and emails the owner with the regulatory citation and action required.
Deadline types to track:
-
HMDA_LAR_ANNUAL_SUBMISSION(Mar 1, 12 CFR Part 1003) RESPA_SECTION_8_ANNUAL_REVIEWFAIR_HOUSING_ACT_VENDOR_AUDITTRID_REGULATION_X_POLICY_REVIEWCFPB_EXAMINATION_PREPARATIONADA_TITLE_III_ACCESSIBILITY_AUDITSOC2_ANNUAL_AUDITNMLSR_LICENSE_RENEWALGLBA_PRIVACY_NOTICE_UPDATEPCI_DSS_QSA_ASSESSMENTANNUAL_PENETRATION_TEST-
FCRA_VENDOR_COMPLIANCE_REVIEW
{
"id": "proptech-deadline-tracker-003",
"name": "PropTech SaaS \u2014 RESPA/Fair Housing/TRID/HMDA Compliance Deadline Tracker",
"nodes": [
{
"id": "n1",
"name": "Weekdays 8 AM",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
200,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1-5"
}
]
}
}
},
{
"id": "n2",
"name": "Load Deadlines",
"type": "n8n-nodes-base.googleSheets",
"typeVersion": 4,
"position": [
420,
300
],
"parameters": {
"operation": "read",
"sheetId": "YOUR_SHEET_ID",
"range": "ComplianceDeadlines!A:F"
}
},
{
"id": "n3",
"name": "Calculate Urgency",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
640,
300
],
"parameters": {
"jsCode": "\nconst today = new Date();\nconst alerts = [];\nfor (const row of $input.all()) {\n const d = row.json;\n const deadline = new Date(d.deadline_date);\n const daysLeft = Math.floor((deadline - today) / 86400000);\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) {\n const alert_key = d.deadline_type + '_' + d.deadline_date;\n if (d.alert_sent_date === new Date().toISOString().split('T')[0]) continue;\n alerts.push({ ...d, daysLeft, tier, alert_key });\n }\n}\nreturn alerts;\n"
}
},
{
"id": "n4",
"name": "Any Alerts?",
"type": "n8n-nodes-base.if",
"typeVersion": 2,
"position": [
860,
300
],
"parameters": {
"conditions": {
"conditions": [
{
"leftValue": "={{ $input.all().length }}",
"operator": {
"type": "number",
"operation": "gt"
},
"rightValue": 0
}
]
}
}
},
{
"id": "n5",
"name": "Slack Compliance Alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [
1080,
200
],
"parameters": {
"channel": "#compliance-ops",
"text": "={{ ($json.tier === 'OVERDUE' ? ':rotating_light:' : $json.tier === 'CRITICAL' ? ':red_circle:' : ':warning:') + ' [' + $json.tier + '] ' + $json.deadline_type + ' \u2014 ' + $json.daysLeft + ' days\\nOwner: ' + $json.owner_email + '\\nCitation: ' + $json.regulation_citation + '\\nDeadline: ' + $json.deadline_date }}"
}
},
{
"id": "n6",
"name": "Gmail Owner",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
1080,
400
],
"parameters": {
"sendTo": "={{ $json.owner_email }}",
"subject": "={{ '[' + $json.tier + '] ' + $json.deadline_type + ' deadline in ' + $json.daysLeft + ' days' }}",
"emailType": "html",
"message": "={{ '<h3>' + $json.deadline_type + '</h3><p>Status: <strong>' + $json.tier + '</strong> (' + $json.daysLeft + ' days remaining)</p><p>Citation: ' + $json.regulation_citation + '</p><p>Action required: ' + $json.action_required + '</p>' }}"
}
}
],
"connections": {
"Weekdays 8 AM": {
"main": [
[
{
"node": "Load Deadlines",
"type": "main",
"index": 0
}
]
]
},
"Load Deadlines": {
"main": [
[
{
"node": "Calculate Urgency",
"type": "main",
"index": 0
}
]
]
},
"Calculate Urgency": {
"main": [
[
{
"node": "Any Alerts?",
"type": "main",
"index": 0
}
]
]
},
"Any Alerts?": {
"main": [
[
{
"node": "Slack Compliance Alert",
"type": "main",
"index": 0
}
],
[
{
"node": "Gmail Owner",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 4: Fair Housing & CFPB Regulatory Incident Pipeline
Problem: A Fair Housing disparate impact alert fires. A CFPB complaint arrives. A RESPA Section 8 kickback pattern is detected in your referral API logs. If these land in a Slack channel and nobody knows the regulatory clock or which lawyer to call, you've already lost days of your response window.
What it does: Receives webhook events for 8 incident types: FAIR_HOUSING_DISPARATE_IMPACT_ALERT, RESPA_SECTION_8_KICKBACK_SUSPICION, HMDA_LAR_DATA_INTEGRITY_ERROR, TRID_DISCLOSURE_TIMING_VIOLATION, CFPB_COMPLAINT_ESCALATION, FAIR_LENDING_REDLINING_FLAG, STATE_AG_INQUIRY_RECEIVED, HUD_COMPLAINT_FILED. Each type maps to the applicable regulation, regulatory body, and response clock. CRITICAL incidents (Fair Housing, RESPA §8, Redlining) route to #legal-compliance with legal team CC. All incidents write to a Postgres audit trail.
Key regulatory clocks this workflow tracks:
- CFPB complaint: 15 calendar days to respond
- HUD Fair Housing complaint: 10 business days to answer
- TRID disclosure timing violation: 3-business-day cure window
- RESPA §8 suspicion: Preserve records immediately (do not delete)
{
"id": "proptech-incident-pipeline-004",
"name": "PropTech SaaS \u2014 Fair Housing & CFPB Regulatory Incident Pipeline",
"nodes": [
{
"id": "n1",
"name": "Incident Webhook",
"type": "n8n-nodes-base.webhook",
"typeVersion": 2,
"position": [
200,
300
],
"parameters": {
"path": "proptech-incident",
"httpMethod": "POST"
}
},
{
"id": "n2",
"name": "Classify Incident",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
420,
300
],
"parameters": {
"jsCode": "\nconst incident_type = $json.incident_type?.toUpperCase();\nconst config = {\n FAIR_HOUSING_DISPARATE_IMPACT_ALERT: {\n severity: 'CRITICAL', slack_channel: '#legal-compliance',\n regulatory_body: 'HUD / DOJ', regulation: 'Fair Housing Act 42 USC \u00a73604/3605',\n response_clock: '10 business days to document model audit',\n legal_cc: true, ciso_bcc: true\n },\n RESPA_SECTION_8_KICKBACK_SUSPICION: {\n severity: 'CRITICAL', slack_channel: '#legal-compliance',\n regulatory_body: 'CFPB', regulation: 'RESPA 12 USC \u00a72607 / 12 CFR 1024.14',\n response_clock: 'Immediate \u2014 preserve referral records, do not delete',\n legal_cc: true, ciso_bcc: false\n },\n HMDA_LAR_DATA_INTEGRITY_ERROR: {\n severity: 'HIGH', slack_channel: '#compliance-ops',\n regulatory_body: 'CFPB / FFIEC', regulation: '12 CFR Part 1003 Regulation C',\n response_clock: 'Correct before annual LAR submission (Mar 1)',\n legal_cc: false, ciso_bcc: false\n },\n TRID_DISCLOSURE_TIMING_VIOLATION: {\n severity: 'HIGH', slack_channel: '#compliance-ops',\n regulatory_body: 'CFPB', regulation: 'TRID 12 CFR \u00a71026.19(e)(1)(iii)',\n response_clock: '3-business-day cure window; document corrective action',\n legal_cc: true, ciso_bcc: false\n },\n CFPB_COMPLAINT_ESCALATION: {\n severity: 'HIGH', slack_channel: '#compliance-ops',\n regulatory_body: 'CFPB', regulation: 'CFPB UDAP 12 USC \u00a75531',\n response_clock: '15 calendar days to respond via CFPB portal',\n legal_cc: true, ciso_bcc: false\n },\n FAIR_LENDING_REDLINING_FLAG: {\n severity: 'CRITICAL', slack_channel: '#legal-compliance',\n regulatory_body: 'DOJ / OCC / FDIC', regulation: 'CRA 12 USC \u00a72901 + Fair Housing Act',\n response_clock: 'Immediate geographic analysis required',\n legal_cc: true, ciso_bcc: true\n },\n STATE_AG_INQUIRY_RECEIVED: {\n severity: 'HIGH', slack_channel: '#legal-compliance',\n regulatory_body: 'State AG', regulation: 'State UDAP / Consumer Protection',\n response_clock: 'Check inquiry letter for state-specific deadline',\n legal_cc: true, ciso_bcc: false\n },\n HUD_COMPLAINT_FILED: {\n severity: 'HIGH', slack_channel: '#legal-compliance',\n regulatory_body: 'HUD', regulation: 'Fair Housing Act 42 USC \u00a73610',\n response_clock: '10 days to answer HUD complaint',\n legal_cc: true, ciso_bcc: false\n }\n};\nconst c = config[incident_type] || { severity: 'MEDIUM', slack_channel: '#compliance-ops', regulatory_body: 'Unknown', regulation: 'Unknown', response_clock: 'Review within 48h', legal_cc: false, ciso_bcc: false };\nreturn { ...$json, ...c, incident_id: 'INC-' + Date.now(), logged_at: new Date().toISOString() };\n"
}
},
{
"id": "n3",
"name": "Slack Immediate Alert",
"type": "n8n-nodes-base.slack",
"typeVersion": 2,
"position": [
640,
200
],
"parameters": {
"channel": "={{ $json.slack_channel }}",
"text": "={{ ':rotating_light: [' + $json.severity + '] PropTech Incident: ' + $json.incident_type + '\\nID: ' + $json.incident_id + '\\nRegulation: ' + $json.regulation + '\\nRegulatory body: ' + $json.regulatory_body + '\\nResponse clock: ' + $json.response_clock }}"
}
},
{
"id": "n4",
"name": "Gmail Legal Team",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
640,
400
],
"parameters": {
"sendTo": "legal@yourcompany.com",
"subject": "={{ '[' + $json.severity + '] PropTech Incident ' + $json.incident_id + ': ' + $json.incident_type }}",
"emailType": "html",
"message": "={{ '<h3>PropTech Regulatory Incident</h3><p>ID: ' + $json.incident_id + '</p><p>Type: ' + $json.incident_type + '</p><p>Regulation: ' + $json.regulation + '</p><p>Regulatory body: ' + $json.regulatory_body + '</p><p>Response clock: ' + $json.response_clock + '</p><p>Customer: ' + ($json.customer_name || 'N/A') + '</p><p>Details: ' + JSON.stringify($json.details || {}) + '</p>' }}"
}
},
{
"id": "n5",
"name": "Postgres Audit Log",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
860,
300
],
"parameters": {
"operation": "insert",
"schema": "public",
"table": "proptech_incidents",
"columns": "incident_id,incident_type,severity,regulation,regulatory_body,response_clock,customer_id,logged_at,raw_payload",
"values": "={{ $json.incident_id }},={{ $json.incident_type }},={{ $json.severity }},={{ $json.regulation }},={{ $json.regulatory_body }},={{ $json.response_clock }},={{ $json.customer_id || '' }},={{ $json.logged_at }},={{ JSON.stringify($json) }}"
}
}
],
"connections": {
"Incident Webhook": {
"main": [
[
{
"node": "Classify Incident",
"type": "main",
"index": 0
}
]
]
},
"Classify Incident": {
"main": [
[
{
"node": "Slack Immediate Alert",
"type": "main",
"index": 0
}
]
]
},
"Slack Immediate Alert": {
"main": [
[
{
"node": "Gmail Legal Team",
"type": "main",
"index": 0
}
]
]
},
"Gmail Legal Team": {
"main": [
[
{
"node": "Postgres Audit Log",
"type": "main",
"index": 0
}
]
]
}
}
}
Workflow 5: Weekly PropTech Platform KPI Dashboard
Problem: Your CEO sees MRR. Your CISO should also see compliance exposure — open Fair Housing incidents, CFPB complaints YTD, HMDA data errors, TRID violations — before an examination does. When both are in the same Monday briefing, the conversation happens before it becomes a crisis.
What it does: Runs every Monday at 8 AM. Queries Postgres for platform metrics (MRR, active accounts, churn, trials) and compliance events (Fair Housing incidents open, CFPB complaints YTD, HMDA errors, TRID violations). Builds an HTML report with colored flags: [FAIR HOUSING INCIDENT OPEN], [HMDA DATA ERROR OPEN], [TRID VIOLATIONS THIS MONTH]. Emails CEO with CISO BCC so the CISO always sees the compliance section.
{
"id": "proptech-kpi-dashboard-005",
"name": "PropTech SaaS \u2014 Weekly Platform KPI Dashboard",
"nodes": [
{
"id": "n1",
"name": "Monday 8 AM",
"type": "n8n-nodes-base.scheduleTrigger",
"typeVersion": 1,
"position": [
200,
300
],
"parameters": {
"rule": {
"interval": [
{
"field": "cronExpression",
"expression": "0 8 * * 1"
}
]
}
}
},
{
"id": "n2",
"name": "Postgres Platform Metrics",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
420,
200
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT COUNT(*) FILTER (WHERE status='active') as active_accounts, SUM(mrr_usd) as total_mrr, COUNT(*) FILTER (WHERE trial_started > NOW()-INTERVAL '7d') as new_trials, COUNT(*) FILTER (WHERE churned_at > NOW()-INTERVAL '7d') as churned_this_week FROM accounts;"
}
},
{
"id": "n3",
"name": "Postgres Compliance Events",
"type": "n8n-nodes-base.postgres",
"typeVersion": 2,
"position": [
420,
400
],
"parameters": {
"operation": "executeQuery",
"query": "SELECT COUNT(*) FILTER (WHERE event_type='FAIR_HOUSING_DISPARATE_IMPACT_ALERT' AND status='OPEN') as fh_incidents_open, COUNT(*) FILTER (WHERE event_type='CFPB_COMPLAINT_ESCALATION' AND created_at > NOW()-INTERVAL '365d') as cfpb_complaints_ytd, COUNT(*) FILTER (WHERE event_type='HMDA_LAR_DATA_INTEGRITY_ERROR' AND status='OPEN') as hmda_errors_open, COUNT(*) FILTER (WHERE event_type='TRID_DISCLOSURE_TIMING_VIOLATION' AND created_at > NOW()-INTERVAL '30d') as trid_violations_30d FROM proptech_incidents;"
}
},
{
"id": "n4",
"name": "Merge",
"type": "n8n-nodes-base.merge",
"typeVersion": 3,
"position": [
640,
300
],
"parameters": {
"mode": "combine",
"combinationMode": "mergeByIndex"
}
},
{
"id": "n5",
"name": "Build HTML Report",
"type": "n8n-nodes-base.code",
"typeVersion": 2,
"position": [
860,
300
],
"parameters": {
"jsCode": "\nconst m = $input.first().json;\nconst flags = [];\nif (m.fh_incidents_open > 0) flags.push('[FAIR HOUSING INCIDENT OPEN \u2014 ' + m.fh_incidents_open + ']');\nif (m.hmda_errors_open > 0) flags.push('[HMDA DATA ERROR OPEN \u2014 ' + m.hmda_errors_open + ']');\nif (m.trid_violations_30d > 0) flags.push('[TRID VIOLATIONS THIS MONTH: ' + m.trid_violations_30d + ']');\n\nconst html = '<h2>Weekly PropTech Platform KPI \u2014 ' + new Date().toDateString() + '</h2>' +\n (flags.length ? '<p style=\"color:red\"><strong>' + flags.join(' | ') + '</strong></p>' : '') +\n '<table border=1 cellpadding=6><tr><th>Metric</th><th>Value</th></tr>' +\n '<tr><td>Active Accounts</td><td>' + m.active_accounts + '</td></tr>' +\n '<tr><td>Total MRR</td><td>$' + Number(m.total_mrr).toLocaleString() + '</td></tr>' +\n '<tr><td>New Trials (7d)</td><td>' + m.new_trials + '</td></tr>' +\n '<tr><td>Churned (7d)</td><td>' + m.churned_this_week + '</td></tr>' +\n '<tr><td>Fair Housing Incidents Open</td><td>' + m.fh_incidents_open + '</td></tr>' +\n '<tr><td>CFPB Complaints YTD</td><td>' + m.cfpb_complaints_ytd + '</td></tr>' +\n '<tr><td>HMDA Data Errors Open</td><td>' + m.hmda_errors_open + '</td></tr>' +\n '<tr><td>TRID Violations (30d)</td><td>' + m.trid_violations_30d + '</td></tr>' +\n '</table>';\nreturn { ...m, html_report: html, flags_summary: flags.join(' | ') || 'No active compliance flags' };\n"
}
},
{
"id": "n6",
"name": "Gmail CEO + CISO BCC",
"type": "n8n-nodes-base.gmail",
"typeVersion": 2,
"position": [
1080,
300
],
"parameters": {
"sendTo": "ceo@yourcompany.com",
"bcc": "ciso@yourcompany.com",
"subject": "={{ 'Weekly PropTech KPI \u2014 ' + new Date().toDateString() + (($json.flags_summary !== 'No active compliance flags') ? ' [ACTION REQUIRED]' : '') }}",
"emailType": "html",
"message": "={{ $json.html_report }}"
}
}
],
"connections": {
"Monday 8 AM": {
"main": [
[
{
"node": "Postgres Platform Metrics",
"type": "main",
"index": 0
}
],
[
{
"node": "Postgres Compliance Events",
"type": "main",
"index": 0
}
]
]
},
"Postgres Platform Metrics": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 0
}
]
]
},
"Postgres Compliance Events": {
"main": [
[
{
"node": "Merge",
"type": "main",
"index": 1
}
]
]
},
"Merge": {
"main": [
[
{
"node": "Build HTML Report",
"type": "main",
"index": 0
}
]
]
},
"Build HTML Report": {
"main": [
[
{
"node": "Gmail CEO + CISO BCC",
"type": "main",
"index": 0
}
]
]
}
}
}
Why PropTech SaaS vendors choose self-hosted n8n
When a CFPB examiner asks 'who processes your borrower data workflows and what third parties have access?' — the answer 'we use Zapier' opens a data-sharing question you don't want to answer in an examination.
| Risk | Zapier/Make | Self-hosted n8n |
|---|---|---|
| HMDA LAR data flows through cloud iPaaS | CFPB data sharing question | Data stays in your VPC |
| Fair Housing AI outputs logged to third-party SaaS | Disparate impact audit scope expansion | All model outputs in-house |
| RESPA referral data through cloud workflow | Kickback exposure in third-party audit trail | Git-versioned, internal only |
| SOC2 CC9.2 vendor risk | Zapier = new sub-processor review | Self-hosted = no external vendor |
| CFPB examination: workflow audit trail | Vendor provides records | You own and produce records |
Self-hosted n8n keeps HMDA LAR data, Fair Housing model outputs, RESPA referral logs, and borrower PII inside your infrastructure. Your incident response audit trail is git-versioned JSON — not a Zapier log you have to request from a third party.
Get these workflows + 10 more for PropTech and compliance-heavy SaaS
All 5 workflows are at stripeai.gumroad.com — copy the JSON, import into n8n, configure your Postgres/Sheets connections.
The FlowKit Complete Bundle also includes onboarding drips, incident pipelines, and KPI dashboards for FinTech, HealthTech, LegalTech, HRTech, and 15+ other compliance-heavy verticals.
Questions? Drop them in the comments — I respond to every one.
Top comments (0)