DEV Community

Alex Kane
Alex Kane

Posted on

n8n for PropTech and RealEstateTech SaaS Vendors: 5 Automations for CFPB RESPA, TRID, HMDA, FinCEN GTO, and AML BSA Compliance

If your PropTech or RealEstateTech SaaS platform handles mortgage origination, title and escrow, HMDA data, or cash transaction reporting, you're operating inside one of the most compliance-dense tech verticals in financial services.

The regulatory exposure is multi-agency and overlapping:

  • CFPB enforces RESPA §8 kickback prohibitions, TRID Loan Estimate timing, and HMDA data accuracy
  • FinCEN requires Geographic Targeting Order (GTO) transaction reports for cash real estate deals
  • FinCEN/DOJ enforce AML/BSA Suspicious Activity Report (SAR) filing obligations
  • FHFA sets MISMO data delivery requirements for Fannie Mae and Freddie Mac
  • State AGs enforce mortgage data breach notification under state laws and GLBA FTC Safeguards

Here's the architecture problem no one is talking about.

When your PropTech SaaS platform runs its TRID Loan Estimate delivery pipeline, HMDA LAR submission workflow, or FinCEN GTO transaction monitoring through a cloud iPaaS tool like Zapier or Make.com, that cloud vendor becomes part of your compliance chain — but it sits outside every regulatory boundary you're responsible for.

The TRID clock doesn't pause for cloud vendor SLA events. CFPB Reg Z §1026.19(e)(1)(iii) requires the Loan Estimate to reach the borrower within 3 business days of application. If your cloud automation platform delays that delivery, the clock does not reset — your SaaS platform is the covered person.

FinCEN GTO records in cloud iPaaS are a FinCEN subpoena target. 31 CFR §1010.230 GTO transaction records stored in or processed through cloud automation become accessible to FinCEN investigators outside your legal team's review window.

HMDA LAR data in cloud automation is in CFPB examination scope. When CFPB examiners review your HMDA LAR submission, they request all data pipeline documentation — including cloud automation workflow logs. Your cloud vendor's run history is now in the exam package.

Self-hosted n8n solves this at the architecture level. Your TRID pipeline, HMDA data, GTO transaction records, and AML/BSA SAR audit trail all stay inside your own infrastructure — no cloud vendor in the chain, no multi-tenant shared logging, no third-party subpoena target.

Here are 5 n8n workflows built specifically for PropTech and RealEstateTech SaaS vendors.


Your Customer Tiers

Before building, define your customer tiers — they drive compliance flag injection at onboarding:

Tier Compliance Exposure
ENTERPRISE_MORTGAGE_PLATFORM TRID §1026.19 + HMDA LAR + RESPA §8 + GLBA FTC Safeguards
TITLE_ESCROW_SAAS FinCEN GTO 31 CFR §1010.230 + AML/BSA SAR + RESPA §8
PROPERTY_MANAGEMENT_SAAS FCRA tenant screening 15 USC §1681 + state rent control + CCPA
REALTOR_MLS_PLATFORM RESPA §8 referral fee tracking + Fair Housing Act + MLS rules
SHORT_TERM_RENTAL_PLATFORM CCPA/GDPR guest data + local STR ordinances + ADA Title III
REIT_PROPTECH_SAAS SEC Reg D/S-11 + FHFA + SOX ICFR + ERISA
PROPTECH_STARTUP SOC 2 Type II + GLBA basic framework + state mortgage licensing

Workflow 1: Tier-Segmented Mortgage SaaS Onboarding Drip

Inject compliance flags at signup and deliver tier-specific regulatory briefings on Day 0, Day 4, and Day 8.

{
  "name": "PropTech SaaS Customer Onboarding Drip",
  "nodes": [
    {
      "id": "trigger",
      "type": "n8n-nodes-base.googleSheetsTrigger",
      "name": "New PropTech Customer",
      "parameters": {
        "sheetId": "YOUR_SHEET_ID",
        "range": "Customers!A:L",
        "event": "rowAdded"
      }
    },
    {
      "id": "classify",
      "type": "n8n-nodes-base.code",
      "name": "Classify Tier + Compliance Flags",
      "parameters": {
        "jsCode": "\nconst row = $json;\nconst tier = row.tier || 'PROPTECH_STARTUP';\nconst flags = {\n  CFPB_RESPA_COVERED: row.respa_covered === 'true',\n  TRID_LENDER_REQUIRED: row.trid_required === 'true',\n  HMDA_LAR_FILER: row.hmda_filer === 'true',\n  AML_BSA_CIP_REQUIRED: row.aml_bsa_required === 'true',\n  FINCEN_GTO_COVERED: row.fincen_gto_covered === 'true',\n  FHFA_CONSERVATORSHIP: row.fhfa_subject === 'true',\n  SOC2_REQUIRED: row.soc2_required === 'true'\n};\nconst tridNote = flags.TRID_LENDER_REQUIRED\n  ? 'TRID ALERT: CFPB Reg Z \u00a71026.19(e)(1)(iii) \u2014 Loan Estimate must reach borrower within 3 business days of application. Cloud iPaaS delay = per-loan CFPB enforcement exposure.'\n  : null;\nconst hmdaNote = flags.HMDA_LAR_FILER\n  ? 'HMDA ALERT: 12 CFR \u00a71003.5 \u2014 LAR must be submitted to CFPB HMDA Platform by March 1. Automation pipeline in cloud iPaaS = CFPB examination scope expansion for LAR data.'\n  : null;\nconst gtoNote = flags.FINCEN_GTO_COVERED\n  ? 'FinCEN GTO ALERT: 31 CFR \u00a71010.230 \u2014 cash real estate transaction records in cloud iPaaS = FinCEN subpoena target outside your legal team review window.'\n  : null;\nconst amlNote = flags.AML_BSA_CIP_REQUIRED\n  ? 'AML/BSA ALERT: 31 USC \u00a75318(h) \u2014 SAR filing deadline is 30 calendar days from suspicious activity detection (60 days if no suspect identified). Cloud automation logs = FinCEN administrative subpoena scope.'\n  : null;\nreturn { tier, flags, tridNote, hmdaNote, gtoNote, amlNote, customerName: row.company_name, email: row.email, csm: row.csm_email };\n"
      }
    },
    {
      "id": "day0_email",
      "type": "n8n-nodes-base.gmail",
      "name": "Day 0 Welcome + Compliance Brief",
      "parameters": {
        "to": "={{ $json.email }}",
        "subject": "Welcome to FlowKit \u2014 Your PropTech Compliance Automation Playbook",
        "message": "={{ 'Hi ' + $json.customerName + ',\\n\\nWelcome to FlowKit. Your account is provisioned.\\n\\n' + ($json.tridNote ? '\u26a0\ufe0f ' + $json.tridNote + '\\n\\n' : '') + ($json.hmdaNote ? '\u26a0\ufe0f ' + $json.hmdaNote + '\\n\\n' : '') + ($json.gtoNote ? '\u26a0\ufe0f ' + $json.gtoNote + '\\n\\n' : '') + ($json.amlNote ? '\u26a0\ufe0f ' + $json.amlNote + '\\n\\n' : '') + 'Your dedicated CSM ' + $json.csm + ' will be in touch within 1 business day.\\n\\nBest,\\nFlowKit Team' }}"
      }
    },
    {
      "id": "slack_csm",
      "type": "n8n-nodes-base.slack",
      "name": "Notify CSM",
      "parameters": {
        "channel": "#new-customers",
        "text": "={{ '\ud83c\udfe0 New PropTech customer: ' + $json.customerName + ' (Tier: ' + $json.tier + '). Compliance flags: ' + JSON.stringify($json.flags) }}"
      }
    },
    {
      "id": "wait_4d",
      "type": "n8n-nodes-base.wait",
      "name": "Wait 4 Days",
      "parameters": {
        "amount": 4,
        "unit": "days"
      }
    },
    {
      "id": "day4_email",
      "type": "n8n-nodes-base.gmail",
      "name": "Day 4 \u2014 TRID/HMDA Setup Guide",
      "parameters": {
        "to": "={{ $json.email }}",
        "subject": "FlowKit Day 4: TRID 3-Day Clock + HMDA LAR Pipeline Setup",
        "message": "TRID Loan Estimate delivery pipeline, HMDA LAR submission automation, and FinCEN GTO transaction monitoring are pre-built. Access your workflow library at stripeai.gumroad.com"
      }
    },
    {
      "id": "wait_4d_2",
      "type": "n8n-nodes-base.wait",
      "name": "Wait 4 More Days",
      "parameters": {
        "amount": 4,
        "unit": "days"
      }
    },
    {
      "id": "day8_email",
      "type": "n8n-nodes-base.gmail",
      "name": "Day 8 \u2014 CFPB Exam Prep",
      "parameters": {
        "to": "={{ $json.email }}",
        "subject": "FlowKit Day 8: CFPB Examination Readiness Checklist",
        "message": "Your CFPB examination readiness checklist: RESPA \u00a78 referral documentation, HMDA LAR accuracy audit, TRID timing logs, AML/BSA SAR audit trail \u2014 all in self-hosted n8n, all audit-ready."
      }
    }
  ],
  "connections": {
    "trigger": {
      "main": [
        [
          "classify"
        ]
      ]
    },
    "classify": {
      "main": [
        [
          "day0_email",
          "slack_csm"
        ]
      ]
    },
    "day0_email": {
      "main": [
        [
          "wait_4d"
        ]
      ]
    },
    "wait_4d": {
      "main": [
        [
          "day4_email"
        ]
      ]
    },
    "day4_email": {
      "main": [
        [
          "wait_4d_2"
        ]
      ]
    },
    "wait_4d_2": {
      "main": [
        [
          "day8_email"
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Workflow 2: CFPB / FinCEN / HMDA Compliance Deadline Tracker

Monitors 12 deadline types across TRID, HMDA, FinCEN GTO, AML/BSA SAR, and CFPB examination obligations. Uses $getWorkflowStaticData to deduplicate alerts within a calendar day.

Fastest regulatory clocks in this series:

Clock Regulation SLA
FinCEN GTO Transaction Report 31 CFR §1010.230 IMMEDIATE at threshold crossing
TRID Loan Estimate Delivery Reg Z §1026.19(e)(1)(iii) 3 business days from application
HMDA LAR Error Correction 12 CFR §1003.6 5 calendar days from discovery
AML/BSA SAR Filing 31 USC §5318(g) 30 calendar days (60 if no suspect)
BSA Currency Transaction Report 31 CFR §1010.311 15 calendar days
CFPB Examination Response 12 USC §5514 Per exam notice schedule
{
  "name": "CFPB / FinCEN / HMDA Compliance Deadline Tracker",
  "nodes": [
    {
      "id": "schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "name": "Daily 7 AM Check",
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 7 * * *"
            }
          ]
        }
      }
    },
    {
      "id": "read_sheet",
      "type": "n8n-nodes-base.googleSheets",
      "name": "Read Compliance Deadlines",
      "parameters": {
        "sheetId": "YOUR_DEADLINES_SHEET_ID",
        "range": "Deadlines!A:H",
        "operation": "read"
      }
    },
    {
      "id": "classify_urgency",
      "type": "n8n-nodes-base.code",
      "name": "Classify Urgency + Dedup",
      "parameters": {
        "jsCode": "\nconst today = new Date();\nconst items = $input.all();\nconst state = $getWorkflowStaticData('global');\nif (!state.alertedToday) state.alertedToday = {};\nconst todayKey = today.toISOString().split('T')[0];\nif (state.alertedToday.date !== todayKey) {\n  state.alertedToday = { date: todayKey, ids: [] };\n}\nconst results = [];\nfor (const item of items) {\n  const d = item.json;\n  const due = new Date(d.due_date);\n  const daysLeft = Math.floor((due - today) / 86400000);\n  const id = d.deadline_id || d.client + '_' + d.deadline_type;\n  if (state.alertedToday.ids.includes(id)) continue;\n  let urgency = null;\n  // Deadline types with fastest regulatory clocks\n  const DEADLINE_TYPES = {\n    'TRID_LOAN_ESTIMATE_3BIZ_DAY': { label: 'TRID Loan Estimate', reg: 'Reg Z \u00a71026.19(e)(1)(iii)', penalty: '$1,000\u2013$5,000/violation' },\n    'TRID_CLOSING_DISCLOSURE_3BIZ_DAY': { label: 'TRID Closing Disclosure', reg: 'Reg Z \u00a71026.19(f)(1)(ii)', penalty: 'per-loan CFPB action' },\n    'HMDA_LAR_ANNUAL_SUBMISSION': { label: 'HMDA LAR Annual Submission', reg: '12 CFR \u00a71003.5 \u2014 March 1', penalty: '$2,000/day CFPB civil money penalty' },\n    'HMDA_LAR_ERROR_CORRECTION_5DAY': { label: 'HMDA LAR Error Correction', reg: '12 CFR \u00a71003.6 \u2014 5 calendar days', penalty: 'material error = resubmission required' },\n    'FINCEN_GTO_REPORT_IMMEDIATE': { label: 'FinCEN GTO Transaction Report', reg: '31 CFR \u00a71010.230 \u2014 at threshold', penalty: 'criminal $500K/civil $1M + BSA criminal 31 USC \u00a75322' },\n    'AML_BSA_SAR_30DAY': { label: 'AML/BSA SAR Filing', reg: '31 USC \u00a75318(g) \u2014 30 calendar days', penalty: '$25K\u2013$1M/day willful violation' },\n    'AML_BSA_CTR_15DAY': { label: 'BSA Currency Transaction Report', reg: '31 CFR \u00a71010.311 \u2014 15 calendar days', penalty: '$500\u2013$1M/violation pattern' },\n    'CFPB_EXAMINATION_RESPONSE': { label: 'CFPB Examination Response', reg: '12 USC \u00a75514 \u2014 per exam notice', penalty: 'consent order / public supervisory action' },\n    'RESPA_ANNUAL_ESCROW_ANALYSIS': { label: 'RESPA Annual Escrow Analysis', reg: '12 CFR \u00a71024.17(f) \u2014 annual', penalty: 'CFPB RESPA enforcement \u00a71024.38' },\n    'HMDA_CRA_ANNUAL_REVIEW': { label: 'HMDA CRA Performance Annual Review', reg: '12 CFR \u00a7228 \u2014 annual', penalty: 'merger/expansion denial' },\n    'SOC2_TYPE2_RENEWAL': { label: 'SOC 2 Type II Renewal', reg: 'AICPA TSC \u2014 annual', penalty: 'customer attrition / enterprise deal loss' },\n    'ANNUAL_PENTEST': { label: 'Annual Penetration Test', reg: 'SOC 2 CC7.1 \u2014 annual', penalty: 'SOC 2 exception finding' }\n  };\n  const meta = DEADLINE_TYPES[d.deadline_type] || { label: d.deadline_type, reg: 'See compliance docs', penalty: 'Unknown' };\n  if (daysLeft < 0) urgency = 'OVERDUE';\n  else if (daysLeft <= 3) urgency = 'CRITICAL';\n  else if (daysLeft <= 14) urgency = 'URGENT';\n  else if (daysLeft <= 30) urgency = 'WARNING';\n  else if (daysLeft <= 60) urgency = 'NOTICE';\n  if (urgency) {\n    state.alertedToday.ids.push(id);\n    results.push({ ...d, daysLeft, urgency, ...meta });\n  }\n}\nreturn results.map(r => ({ json: r }));\n"
      }
    },
    {
      "id": "route",
      "type": "n8n-nodes-base.switch",
      "name": "Route by Urgency",
      "parameters": {
        "rules": {
          "values": [
            {
              "value": "OVERDUE"
            },
            {
              "value": "CRITICAL"
            },
            {
              "value": "URGENT"
            },
            {
              "value": "WARNING"
            },
            {
              "value": "NOTICE"
            }
          ]
        },
        "dataPropertyName": "urgency"
      }
    },
    {
      "id": "slack_overdue",
      "type": "n8n-nodes-base.slack",
      "name": "Slack \u2014 OVERDUE",
      "parameters": {
        "channel": "#compliance-alerts",
        "text": "={{ '\ud83d\udea8 OVERDUE [' + $json.deadline_type + '] ' + $json.client + ' \u2014 ' + $json.label + ' (' + $json.reg + '). Penalty: ' + $json.penalty + '. ' + Math.abs($json.daysLeft) + ' days past due.' }}"
      }
    },
    {
      "id": "slack_critical",
      "type": "n8n-nodes-base.slack",
      "name": "Slack \u2014 CRITICAL",
      "parameters": {
        "channel": "#compliance-alerts",
        "text": "={{ '\ud83d\udd34 CRITICAL [' + $json.deadline_type + '] ' + $json.client + ' \u2014 ' + $json.daysLeft + ' days left. ' + $json.label + ' (' + $json.reg + ').' }}"
      }
    },
    {
      "id": "gmail_urgent",
      "type": "n8n-nodes-base.gmail",
      "name": "Gmail \u2014 URGENT",
      "parameters": {
        "to": "compliance@yourcompany.com",
        "subject": "={{ '[URGENT] ' + $json.label + ' due in ' + $json.daysLeft + ' days \u2014 ' + $json.client }}",
        "message": "={{ $json.label + ' for ' + $json.client + '\\nRegulation: ' + $json.reg + '\\nDue: ' + $json.due_date + '\\nDays remaining: ' + $json.daysLeft + '\\nPenalty exposure: ' + $json.penalty }}"
      }
    }
  ],
  "connections": {
    "schedule": {
      "main": [
        [
          "read_sheet"
        ]
      ]
    },
    "read_sheet": {
      "main": [
        [
          "classify_urgency"
        ]
      ]
    },
    "classify_urgency": {
      "main": [
        [
          "route"
        ]
      ]
    },
    "route": {
      "main": [
        [
          "slack_overdue"
        ],
        [
          "slack_critical"
        ],
        [
          "gmail_urgent"
        ],
        [],
        []
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Workflow 3: Mortgage & Title API Health Monitor

Polls 5 critical API endpoints every 15 minutes. Uses $getWorkflowStaticData for 30-minute alert suppression. Each endpoint is annotated with its specific compliance consequence if it goes down.

Endpoint Compliance Annotation
MISMO delivery API FHFA GSE loan delivery gap
HMDA LAR submission API CFPB HMDA Platform §1003.5
FinCEN BSA eFiling API SAR/CTR/GTO filing delay = BSA penalty
TRID calculation API 3-business-day Loan Estimate clock at risk
Property valuation API RESPA §8 appraisal independence exposure
{
  "name": "Mortgage & Title API Health Monitor",
  "nodes": [
    {
      "id": "schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "name": "Every 15 Minutes",
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "*/15 * * * *"
            }
          ]
        }
      }
    },
    {
      "id": "check_endpoints",
      "type": "n8n-nodes-base.code",
      "name": "Define Endpoints",
      "parameters": {
        "jsCode": "\nreturn [\n  { json: { name: 'mismo_delivery_api', url: '{{ $vars.MISMO_API_URL }}/health', compliance: 'FHFA MISMO delivery \u2014 FNMA/FHLMC system failure = GSE loan delivery gap' } },\n  { json: { name: 'hmda_lar_submission_api', url: '{{ $vars.HMDA_API_URL }}/health', compliance: 'CFPB HMDA Platform (12 CFR \u00a71003.5) \u2014 March 1 LAR deadline not dependent on platform SLA' } },\n  { json: { name: 'fincen_bsa_efiling_api', url: '{{ $vars.FINCEN_API_URL }}/health', compliance: 'FinCEN BSA E-Filing (31 CFR \u00a71010.230) \u2014 SAR/CTR/GTO filing delay = per-day BSA penalty 31 USC \u00a75322' } },\n  { json: { name: 'trid_calculation_api', url: '{{ $vars.TRID_API_URL }}/health', compliance: 'TRID Reg Z \u00a71026.19(e) \u2014 Loan Estimate calculation failure = 3-business-day delivery clock at risk' } },\n  { json: { name: 'property_valuation_api', url: '{{ $vars.VALUATION_API_URL }}/health', compliance: 'USPAP/FIRREA appraisal independence \u2014 cloud vendor downtime during appraisal window = RESPA \u00a78 exposure' } }\n];\n"
      }
    },
    {
      "id": "http_check",
      "type": "n8n-nodes-base.httpRequest",
      "name": "HTTP Health Check",
      "parameters": {
        "url": "={{ $json.url }}",
        "method": "GET",
        "timeout": 10000,
        "continueOnFail": true
      }
    },
    {
      "id": "evaluate",
      "type": "n8n-nodes-base.code",
      "name": "Evaluate Status",
      "parameters": {
        "jsCode": "\nconst state = $getWorkflowStaticData('global');\nconst endpoint = $('check_endpoints').first().json;\nconst status = $json.statusCode === 200 ? 'OK' : 'CRITICAL';\nconst key = endpoint.name;\nconst now = Date.now();\nif (status === 'OK') { state[key] = null; return []; }\nif (state[key] && (now - state[key]) < 1800000) return [];\nstate[key] = now;\nreturn [{ json: { ...endpoint, status, statusCode: $json.statusCode, alertedAt: new Date().toISOString() } }];\n"
      }
    },
    {
      "id": "slack_alert",
      "type": "n8n-nodes-base.slack",
      "name": "Slack API Alert",
      "parameters": {
        "channel": "#platform-ops",
        "text": "={{ '\ud83d\udd34 API DOWN: ' + $json.name + ' | Status: ' + $json.statusCode + '\\nCompliance risk: ' + $json.compliance + '\\nAlerting at: ' + $json.alertedAt }}"
      }
    }
  ],
  "connections": {
    "schedule": {
      "main": [
        [
          "check_endpoints"
        ]
      ]
    },
    "check_endpoints": {
      "main": [
        [
          "http_check"
        ]
      ]
    },
    "http_check": {
      "main": [
        [
          "evaluate"
        ]
      ]
    },
    "evaluate": {
      "main": [
        [
          "slack_alert"
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Workflow 4: FinCEN / CFPB / RESPA Incident Pipeline

Classifies 8 incident types by severity with exact regulatory clock, mandatory notification recipients, and self-hosting rationale. Routes P0 incidents to Slack + email simultaneously.

Incident Type SLA Severity
FINCEN_GTO_THRESHOLD_CROSSED IMMEDIATE — 31 CFR §1010.230 P0
AML_BSA_SAR_REQUIRED 30 calendar days — 31 USC §5318(g) P0
TRID_TIMING_VIOLATION_DETECTED 3 business days — §1026.19(e)(1)(iii) P0
CFPB_EXAMINATION_OPENED IMMEDIATE — 12 USC §5514 P0
HMDA_LAR_MATERIAL_ERROR 5 calendar days — 12 CFR §1003.6 P1
RESPA_SECTION8_KICKBACK_COMPLAINT 60 calendar days P1
FHFA_GSE_DELIVERY_FAILURE IMMEDIATE — GSE seller-servicer guide P1
DATA_BREACH_MORTGAGE_PII 72 hours — GLBA / state AG / GDPR P0
{
  "name": "FinCEN / CFPB / RESPA Incident Pipeline",
  "nodes": [
    {
      "id": "webhook",
      "type": "n8n-nodes-base.webhook",
      "name": "Incident Webhook",
      "parameters": {
        "path": "proptech-incident",
        "method": "POST"
      }
    },
    {
      "id": "classify",
      "type": "n8n-nodes-base.code",
      "name": "Classify Incident Type + Clock",
      "parameters": {
        "jsCode": "\nconst inc = $json;\nconst INCIDENT_TYPES = {\n  'FINCEN_GTO_THRESHOLD_CROSSED': {\n    sla: 'IMMEDIATE \u2014 31 CFR \u00a71010.230 transaction report required at crossing',\n    severity: 'P0', notify: 'BSA Officer + Legal + CEO',\n    note: 'Each transaction at/above threshold = separate FinCEN GTO filing. No aggregation exception. $500K civil / criminal referral.'\n  },\n  'AML_BSA_SAR_REQUIRED': {\n    sla: '30 calendar days from detection \u2014 31 USC \u00a75318(g) (60d if no suspect)',\n    severity: 'P0', notify: 'BSA Officer + CISO + Legal',\n    note: 'SAR in cloud iPaaS = FinCEN administrative subpoena target outside legal hold. Self-hosted n8n = SAR pipeline stays inside your BSA boundary.'\n  },\n  'TRID_TIMING_VIOLATION_DETECTED': {\n    sla: '3 business days \u2014 Reg Z \u00a71026.19(e)(1)(iii) Loan Estimate delivery clock',\n    severity: 'P0', notify: 'Compliance Officer + CCO + Legal',\n    note: 'Per-loan CFPB violation. TRID clock starts at application receipt, not at automation platform delivery. Cloud vendor SLA does not stop the clock.'\n  },\n  'HMDA_LAR_MATERIAL_ERROR': {\n    sla: '5 calendar days \u2014 12 CFR \u00a71003.6 error correction window',\n    severity: 'P1', notify: 'Compliance Officer + CCO',\n    note: 'Material HMDA error = mandatory CFPB resubmission. LAR data in cloud iPaaS = CFPB examination scope includes cloud vendor audit logs.'\n  },\n  'CFPB_EXAMINATION_OPENED': {\n    sla: 'IMMEDIATE \u2014 12 USC \u00a75514 examination authority',\n    severity: 'P0', notify: 'CEO + General Counsel + CCO + CISO',\n    note: 'CFPB examination scope: all automation logs, workflow audit trails, data retention records. Cloud iPaaS workflow logs = examiner document request scope.'\n  },\n  'RESPA_SECTION8_KICKBACK_COMPLAINT': {\n    sla: '60 calendar days \u2014 RESPA \u00a78 investigation response window',\n    severity: 'P1', notify: 'General Counsel + CCO + BSA Officer',\n    note: 'RESPA \u00a78 referral fee / kickback allegations. All MSA documentation, referral data, payment records \u2014 if in cloud automation = discoverable outside privilege.'\n  },\n  'FHFA_GSE_DELIVERY_FAILURE': {\n    sla: 'IMMEDIATE \u2014 FHFA directive / GSE seller-servicer guide',\n    severity: 'P1', notify: 'CTO + CCO',\n    note: 'MISMO data delivery failure to Fannie Mae/Freddie Mac = loan purchase refusal. Self-hosted n8n = delivery pipeline isolation from multi-tenant cloud outages.'\n  },\n  'DATA_BREACH_MORTGAGE_PII': {\n    sla: '72 hours \u2014 GDPR Art.33 / state AG notification / GLBA FTC Safeguards Rule',\n    severity: 'P0', notify: 'CISO + Legal + CEO',\n    note: 'Mortgage application data: SSN, income, employment, credit score \u2014 full GLBA NPI + CCPA + state AG notification triggers.'\n  }\n};\nconst type = inc.incident_type || 'UNKNOWN';\nconst meta = INCIDENT_TYPES[type] || { sla: 'See compliance docs', severity: 'P2', notify: 'Compliance Officer', note: 'Unknown incident type' };\nreturn [{ json: { ...inc, ...meta, incident_type: type, logged_at: new Date().toISOString() } }];\n"
      }
    },
    {
      "id": "route_severity",
      "type": "n8n-nodes-base.switch",
      "name": "Route by Severity",
      "parameters": {
        "rules": {
          "values": [
            {
              "value": "P0"
            },
            {
              "value": "P1"
            },
            {
              "value": "P2"
            }
          ]
        },
        "dataPropertyName": "severity"
      }
    },
    {
      "id": "p0_slack",
      "type": "n8n-nodes-base.slack",
      "name": "P0 \u2014 Immediate Alert",
      "parameters": {
        "channel": "#incidents-p0",
        "text": "={{ '\ud83d\udea8 P0 INCIDENT [' + $json.incident_type + ']\\nClient: ' + $json.client_id + '\\nSLA: ' + $json.sla + '\\nNotify: ' + $json.notify + '\\nNote: ' + $json.note }}"
      }
    },
    {
      "id": "p0_email",
      "type": "n8n-nodes-base.gmail",
      "name": "P0 \u2014 Email Leadership",
      "parameters": {
        "to": "ceo@yourcompany.com",
        "cc": "legal@yourcompany.com",
        "subject": "={{ '[P0 INCIDENT] ' + $json.incident_type + ' \u2014 ' + $json.client_id }}",
        "message": "={{ 'INCIDENT TYPE: ' + $json.incident_type + '\\nSLA: ' + $json.sla + '\\nNotify: ' + $json.notify + '\\nNote: ' + $json.note + '\\nLogged: ' + $json.logged_at }}"
      }
    },
    {
      "id": "p1_slack",
      "type": "n8n-nodes-base.slack",
      "name": "P1 \u2014 Alert + Log",
      "parameters": {
        "channel": "#incidents-p1",
        "text": "={{ '\ud83d\udd34 P1 INCIDENT [' + $json.incident_type + '] Client: ' + $json.client_id + ' | SLA: ' + $json.sla }}"
      }
    },
    {
      "id": "log_sheet",
      "type": "n8n-nodes-base.googleSheets",
      "name": "Log All Incidents",
      "parameters": {
        "sheetId": "YOUR_INCIDENT_LOG_SHEET",
        "range": "Incidents!A:J",
        "operation": "append",
        "data": {
          "values": [
            [
              "={{ $json.logged_at }}",
              "={{ $json.incident_type }}",
              "={{ $json.client_id }}",
              "={{ $json.severity }}",
              "={{ $json.sla }}",
              "={{ $json.notify }}"
            ]
          ]
        }
      }
    }
  ],
  "connections": {
    "webhook": {
      "main": [
        [
          "classify"
        ]
      ]
    },
    "classify": {
      "main": [
        [
          "route_severity",
          "log_sheet"
        ]
      ]
    },
    "route_severity": {
      "main": [
        [
          "p0_slack"
        ],
        [
          "p1_slack"
        ],
        []
      ]
    },
    "p0_slack": {
      "main": [
        [
          "p0_email"
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Workflow 5: Weekly PropTech SaaS KPI Dashboard

Queries Postgres for MRR, active customers by compliance tier, open incidents, and critical deadline counts. Emails CEO + CCO + CISO every Monday at 8 AM.

{
  "name": "Weekly PropTech SaaS KPI Dashboard",
  "nodes": [
    {
      "id": "schedule",
      "type": "n8n-nodes-base.scheduleTrigger",
      "name": "Monday 8 AM",
      "parameters": {
        "rule": {
          "interval": [
            {
              "field": "cronExpression",
              "expression": "0 8 * * 1"
            }
          ]
        }
      }
    },
    {
      "id": "query_db",
      "type": "n8n-nodes-base.postgres",
      "name": "Query PropTech KPIs",
      "parameters": {
        "operation": "executeQuery",
        "query": "\nWITH weekly AS (\n  SELECT\n    COUNT(DISTINCT customer_id) FILTER (WHERE status = 'active') AS active_customers,\n    COUNT(DISTINCT customer_id) FILTER (WHERE tier = 'ENTERPRISE_MORTGAGE_PLATFORM') AS enterprise_mortgage_accounts,\n    COUNT(DISTINCT customer_id) FILTER (WHERE flags @> '{\"TRID_LENDER_REQUIRED\": true}') AS trid_accounts,\n    COUNT(DISTINCT customer_id) FILTER (WHERE flags @> '{\"HMDA_LAR_FILER\": true}') AS hmda_accounts,\n    COUNT(DISTINCT customer_id) FILTER (WHERE flags @> '{\"FINCEN_GTO_COVERED\": true}') AS fincen_gto_accounts,\n    COUNT(DISTINCT customer_id) FILTER (WHERE flags @> '{\"AML_BSA_CIP_REQUIRED\": true}') AS aml_bsa_accounts,\n    SUM(mrr_usd) AS total_mrr,\n    SUM(mrr_usd) - LAG(SUM(mrr_usd)) OVER (ORDER BY date_trunc('week', created_at)) AS mrr_change_wow\n  FROM customers\n  WHERE created_at >= NOW() - INTERVAL '7 days'\n),\nincidents AS (\n  SELECT\n    COUNT(*) FILTER (WHERE incident_type = 'TRID_TIMING_VIOLATION_DETECTED' AND created_at >= NOW() - INTERVAL '7 days') AS trid_violations_7d,\n    COUNT(*) FILTER (WHERE incident_type LIKE 'AML%' AND created_at >= NOW() - INTERVAL '7 days') AS aml_incidents_7d,\n    COUNT(*) FILTER (WHERE incident_type = 'FINCEN_GTO_THRESHOLD_CROSSED' AND created_at >= NOW() - INTERVAL '7 days') AS gto_reports_7d,\n    COUNT(*) FILTER (WHERE severity = 'P0' AND status = 'open') AS p0_incidents_open,\n    COUNT(*) FILTER (WHERE deadline_type IN ('TRID_LOAN_ESTIMATE_3BIZ_DAY','HMDA_LAR_ANNUAL_SUBMISSION') AND status = 'OVERDUE') AS critical_deadlines_overdue\n  FROM incidents\n)\nSELECT w.*, i.* FROM weekly w, incidents i;\n"
      }
    },
    {
      "id": "build_report",
      "type": "n8n-nodes-base.code",
      "name": "Build HTML KPI Report",
      "parameters": {
        "jsCode": "\nconst d = $json;\nconst html = `<h2>\ud83d\udcca FlowKit PropTech SaaS \u2014 Weekly KPI Dashboard</h2>\n<table border=\"1\" cellpadding=\"6\" style=\"border-collapse:collapse\">\n<tr><th>Metric</th><th>Value</th></tr>\n<tr><td>Active Customers</td><td>${d.active_customers}</td></tr>\n<tr><td>Enterprise Mortgage Accounts</td><td>${d.enterprise_mortgage_accounts}</td></tr>\n<tr><td>TRID-Required Accounts</td><td>${d.trid_accounts}</td></tr>\n<tr><td>HMDA LAR Filer Accounts</td><td>${d.hmda_accounts}</td></tr>\n<tr><td>FinCEN GTO-Covered Accounts</td><td>${d.fincen_gto_accounts}</td></tr>\n<tr><td>AML/BSA CIP Accounts</td><td>${d.aml_bsa_accounts}</td></tr>\n<tr><td>Total MRR (USD)</td><td>$${d.total_mrr?.toLocaleString()}</td></tr>\n<tr><td>MRR Change WoW</td><td>$${d.mrr_change_wow?.toLocaleString()}</td></tr>\n<tr style=\"background:#fff3cd\"><td>TRID Violations (7d)</td><td>${d.trid_violations_7d}</td></tr>\n<tr style=\"background:#fff3cd\"><td>AML Incidents (7d)</td><td>${d.aml_incidents_7d}</td></tr>\n<tr style=\"background:#fff3cd\"><td>FinCEN GTO Reports (7d)</td><td>${d.gto_reports_7d}</td></tr>\n<tr style=\"background:#f8d7da\"><td>P0 Incidents Open</td><td>${d.p0_incidents_open}</td></tr>\n<tr style=\"background:#f8d7da\"><td>Critical Deadlines Overdue</td><td>${d.critical_deadlines_overdue}</td></tr>\n</table>`;\nreturn [{ json: { html } }];\n"
      }
    },
    {
      "id": "send_email",
      "type": "n8n-nodes-base.gmail",
      "name": "Email CEO + CCO + CISO",
      "parameters": {
        "to": "ceo@yourcompany.com",
        "bcc": "cco@yourcompany.com,ciso@yourcompany.com",
        "subject": "FlowKit Weekly PropTech KPI \u2014 {{ $now.format('YYYY-MM-DD') }}",
        "message": "={{ $json.html }}"
      }
    }
  ],
  "connections": {
    "schedule": {
      "main": [
        [
          "query_db"
        ]
      ]
    },
    "query_db": {
      "main": [
        [
          "build_report"
        ]
      ]
    },
    "build_report": {
      "main": [
        [
          "send_email"
        ]
      ]
    }
  }
}
Enter fullscreen mode Exit fullscreen mode

Why Self-Hosted n8n Specifically for PropTech/RealEstateTech SaaS

FinCEN GTO 31 CFR §1010.230 subpoena boundary: Geographic Targeting Order transaction records in cloud iPaaS = FinCEN investigators can reach the vendor directly outside your legal hold. Self-hosted n8n = GTO data stays in your BSA-controlled environment.

TRID §1026.19(e) per-loan violation boundary: The 3-business-day Loan Estimate clock is a per-loan CFPB violation. Cloud vendor SLA does not create a regulatory defense. Self-hosted n8n = TRID delivery pipeline isolated from multi-tenant cloud events.

HMDA LAR CFPB examination scope: CFPB examiners request all data pipeline documentation in HMDA LAR reviews. Cloud automation workflow logs = in scope. Self-hosted n8n = workflow logs inside your CFPB examination perimeter, not in a third-party system.

AML/BSA SAR 31 USC §5318(g) litigation privilege: FinCEN administrative subpoena authority reaches cloud automation platforms directly. SAR investigation records in cloud iPaaS = outside attorney-client privilege boundary. Self-hosted n8n = SAR pipeline inside your BSA officer's controlled infrastructure.

GLBA FTC Safeguards Rule data perimeter: Mortgage application NPI (SSN, income, credit score) in cloud automation = 2023 GLBA Safeguards Rule §314.4(f) service provider oversight obligation. Self-hosted n8n = NPI stays inside your documented safeguards boundary.


Get These Workflows

All 5 workflows — plus the full FlowKit n8n automation template library — are available at stripeai.gumroad.com.

Individual templates: $12–$29 | Complete bundle (15 templates): $97

Top comments (0)