n8n Automation Stack
A self-hosted n8n workflow-automation hub running 23 production workflows for lead intake, transaction management, and operational digests, with source-controlled workflow…
- 23
- workflows in the active production set
- 8am/8pm ET
- daily digest and quiet-hours window enforced by the send gate
Automation plumbing. The canvases contain live credentials and client-facing message templates, so only the shape is described.
- 01Edge
- Cloudflare Access
- 02Data
- PostgreSQL
- 03Integrations
- n8n
- Resend
- 04Operations
- Docker Compose
- Uptime Kuma
- 05Supporting
- ntfy
What is shown instead is the verified stack by layer. Layers, not connections — which service calls which is not something a dependency list can prove. 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. 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 behind it.
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, not edited ad hoc in the n8n UI. Each is 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, not 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, never committed. 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 — a broken suppression check blocks the send instead of 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, instead of dropping or blocking the lead.
A global error-handler workflow is wired as the failure path for every other workflow. It sends 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." That single point of entry 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, not 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 instead of 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, so 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. Within the email layer, the renderer decision cuts the same way. 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. 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. 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. 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. That's why the error path was validated with a dedicated live webhook test instead of 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. That bug was fixed and covered with a passing test suite before the lead-scoring workflow was trusted to depend on it.
Outcome
Twenty-three workflows now make up the active production set, handling error alerting, message-send gating, a consolidated weekly brief, lead intake and alerting, no-touch follow-up, and transaction lifecycle management. Nightly database backups and uptime monitoring with push-based alerting back the whole stack. 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 produced 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.
In mid-September 2026 seven separate report workflows, several of which had drifted into disagreeing on the same transaction figures, were consolidated into a single weekly operational brief with one source per fact. The retired seven stay in version control and importable but are forced inactive by the import script. A dedicated new-lead alert followed, polling the CRM on a short interval and notifying the internal team of each new lead, backed by its own uptime heartbeat. The daily no-touch follow-up ladder was refined the same week to treat any outgoing communication as contact, and agents, vendors and lenders are now excluded from being counted as leads across the alert, the ladder and the weekly brief.
Related work
- Live2026AtumA self-hosted platform that scores social content against each creator's own baseline for real outliers, then turns validated winners into original, similarity-checked scripts.
- Live2026Evolve Agentic SiteA 61-page trilingual marketing and productized-service site with its own tiered pricing engine, four live D1-backed lead endpoints, and a documented history of pricing model…
- Live2026Evolve StoresA static-site generator that builds 32 independent brand storefronts from one codebase, with build-time voice and brand-isolation gates and gated digital delivery.