n8n Automation Stack
A self-hosted n8n workflow-automation hub running seven production workflows for lead intake, transaction management, and operational digests, with source-controlled workflow…
- 7
- production workflows live
- 8am/8pm ET
- daily digest and quiet-hours window enforced by the send gate
- Cloudflare Access
- PostgreSQL
- Docker Compose
- Uptime Kuma
- n8n
- Resend
- ntfy
n8n Automation Stack holds live data, so this shows the verified technology stack by layer rather than a screenshot. Hosts, ports and topology are deliberately absent.
Problem
Running a real estate operation generates a constant stream of small, time-sensitive coordination work — new leads need scoring and CRM entry the moment they arrive, transaction checklists need to advance as contract dates pass, and daily status needs to reach the right person without anyone manually checking four separate systems. Wiring that by hand in each source system doesn't scale, and building it as bespoke code per integration means every new automation is a new maintenance burden. The stack needed one automation layer that could be version-controlled like software, not configured only through a UI that leaves no audit trail.
What was built
The n8n stack is the automation backbone for the operation: seven live workflows handle a global error handler, a gated message-send layer, a daily operational digest, lead intake from the public site, and transaction lifecycle management (checklist generation, deadline watchdogs, and status advancement). Every workflow is defined as a JSON file committed to the repo rather than edited ad hoc in the n8n UI, imported and published through scripts so the running system's state always traces back to a reviewable file. When a workflow needs AI reasoning — for example, scoring an inbound lead — it never calls a model API directly; it calls a single internal gateway service that enforces a monthly spend cap and logs every call, so agentic steps stay deterministic sub-tasks inside an otherwise rule-based pipeline rather than open-ended autonomous reasoning.
Technical approach
The operational model treats the n8n UI as a read-only view onto live state, not a source of truth: workflows live as JSON files with stable IDs (so re-import is idempotent), secrets are injected as placeholders at import time from an OS credential store rather than ever being committed, and every workflow update requires an explicit re-import-and-restart cycle since the engine only picks up changes after restart. A dedicated Safe Send sub-workflow sits in front of every outbound email or SMS as a gating layer: it checks a suppression list, enforces an 8am-8pm local-time send window, and fails closed on any lookup error — meaning a broken suppression check blocks the send rather than risking one going out against a suppression it couldn't verify. The lead-intake workflow is explicitly built to be AI-outage-proof: it degrades gracefully to a non-AI path if the scoring gateway is unreachable rather than dropping or blocking the lead. A global error-handler workflow is wired as the failure path for every other workflow, sending both an email with the failing workflow, execution ID, and last node, and a high-priority push alert, so failures surface immediately instead of silently stalling a pipeline. All AI-reasoning steps route through one internal gateway endpoint under a bearer token specifically because the house rule for this stack is 'agent steps call the gateway, never the raw model API' — a single point of entry that caps monthly spend, centralizes audit logging, and keeps raw model credentials out of every individual workflow.
Creative approach
Craft
This is operational backend infrastructure with a workflow-editor UI supplied by the platform, not a designed product surface — but the outbound-email layer became a genuine design pass. The starting state was every sender using Resend plain-text sends only: ALL-CAPS headers, asterisk bullets, one flat format for every message. A dedicated email-renderer sub-workflow replaced that with a single JS template, covered by its own test suite, that generates matching HTML and plain-text output from one structured input so the two can't drift apart. The daily digest got stat tiles, a deadline table, and task chips, split into separate morning and evening editions; the deadline watchdog and error handler got a banded terracotta-and-amber report card; every send carries preheader text so it previews cleanly in an inbox list. The one deliberate exception is the global error handler, which does not route through the shared renderer at all — a renderer bug must never be the reason a failure alert fails to render, so its HTML stays inline and dependency-free.
Reframe
Treating n8n workflow JSON as source code rather than UI state is what makes the whole thing operable as infrastructure instead of a fragile pile of manual configuration: it enables disaster recovery, credential rotation, and code review on automations that would otherwise live only inside a database nobody diffs. The second load-bearing decision is routing every AI step through one spend-capped, audited gateway rather than letting each workflow hold its own model credentials — that single choice is what keeps a growing set of 'agentic' automations from turning into an unbounded and unaccountable AI spend surface. A third decision followed from the first production incident with that gateway: n8n originally shared the operator's own gateway token, meaning n8n's AI calls billed against the same monthly cap as every other agent using it. That was split onto a dedicated service account with its own $25/month cap, so a runaway lead-scoring loop inside one workflow can no longer silently eat the budget of an unrelated tool. And within the email layer, the renderer decision cuts the same way as the gateway decision: the error handler intentionally does not depend on the same template pipeline it might one day be reporting a bug in.
Process and what failed
The workflow set was built in stages and explicitly paused mid-build once — the CRM-related workflows were held while a separate CRM platform (Chrysalis) underwent a cutover, and only resumed once that dependency stabilized. The lead-intake workflow was deliberately hardened to survive an AI-gateway outage after the team recognized that an AI-dependent lead pipeline that silently drops leads during an outage is worse than one that degrades to a simpler non-AI path. The message-send gate's fail-closed suppression check was a specific decision documented as intentional: better to skip an optional message than risk violating an opt-out.
Several other failure modes were only caught because production traffic surfaced them. The CRM's API parses a Docker-internal hostname as a tenant subdomain and returns a 404 instead of a real error, so every workflow node that calls it now carries an explicit forwarded-host header to avoid the misparse. n8n's own engine also refuses to run unpublished workflows anywhere, error workflows and sub-workflows included, and only picks up a JSON change after the container is restarted, so editing the file is never itself the deploy step. On the testing side, a CLI-executed workflow run cannot trigger the global error handler — only a production-triggered execution can — which is why the error path was validated with a dedicated live webhook test rather than trusted from a local run, and it was later validated again by a genuine unplanned production failure. The digest's "since this morning" deltas depend on a snapshot n8n only persists on scheduled runs, so that comparison logic was unverifiable in local testing and only proved out on the first real morning firing. A heartbeat node pointed at an unconfigured monitoring URL was originally failing loudly on every run; rather than leave a permanently red monitor that trains the operator to ignore alerts, the import script was changed to detect the missing configuration and disable the node instead. Wiring n8n's AI steps through the internal gateway also surfaced a live bug in that gateway: an upstream AI failure was returning an empty HTTP 200 instead of a visible error, which was fixed and covered with a passing test suite before the lead-scoring workflow was trusted to depend on it.
Outcome
Seven workflows run live in production handling error alerting, message-send gating, daily digests, lead intake, and transaction lifecycle management, backed by nightly database backups and uptime monitoring with push-based alerting. The transaction sweeper's idempotent checklist generation was run once against the full existing deal set and produced 21 deals, 1,155 tasks, and 21 roadmaps with zero duplicate emails sent — the congrats-email dedupe logic held against a real backfill, not just a test fixture. The global error handler has been verified live twice: once by a synthetic failure fired through a dedicated webhook test, and once by a genuine unplanned production failure, both producing the expected email-plus-push alert. n8n's own AI usage now runs on a dedicated service account with its own monthly spend cap, separated from every other tool's budget after an earlier design shared one token across all callers. The stack functions as the automation layer between the public-facing site, the CRM, and the operator's daily workflow, with every workflow's live behavior traceable to a version-controlled JSON definition.