Stay Out of Spam: Deliverability, Reputation & Compliance for n8n Email Flows

  • |
  •  admin

Introduction

Scaling email with n8n is easy. Scaling safely—without burning your domain or annoying busy recipients—is the real craft. Deliverability is a mix of protocol hygiene (SPF/DKIM/DMARC), sending patterns (warm‑up, pacing, consistency), message quality (HTML, links, preview lines), and respect (unsubscribe and suppression policies across campaigns). Compliance adds another layer: know what you’re allowed to send, keep the data you need (and only that), and stop when asked.

In this guide, we share the operational practices LogicalStreet Technology Pvt. Ltd. uses to keep email flows out of spam and inside the lines—designed specifically for n8n. We’ll configure the DNS bedrock, warm new senders responsibly, design flows with Split in Batches and Wait nodes, keep content lean, and wire up suppression and monitoring so problems don’t snowball.

1) Protocol Basics: SPF, DKIM, DMARC—what they do & how to verify

SPF (Sender Policy Framework)

What

A TXT record listing IPs/services allowed to send mail for your domain.

Why

Prevents spoofing; mailbox providers check if the sending server is authorized.

@ TXT v=spf1 include:_spf.google.com include:send.example.com ~all
  • Keep it short; SPF has a 10‑lookup limit. Use provider includes instead of many ip4: entries.
  • End with ~all (softfail) during rollout, then consider -all after verifying all sources.

DKIM (DomainKeys Identified Mail)

What

Cryptographic signature added by your sending server; receivers verify with your public key in DNS.

Why

Proves the message wasn’t tampered with and truly came from your domain.

selector1._domainkey TXT v=DKIM1; k=rsa; p=MIIBIjANBgkqh…IDAQAB
  • Use 2048‑bit keys where supported and rotate selectors periodically.
  • Ensure your provider actually signs outbound mail.

DMARC (Domain‑based Message Authentication, Reporting & Conformance)

What

Policy telling receivers what to do when SPF/DKIM fail and where to send reports.

Why

Aligns “From” domain with SPF/DKIM; enables feedback reports.

_dmarc TXT v=DMARC1; p=quarantine; rua=mailto:dmarc-agg@yourdomain.com; ruf=mailto:dmarc-forensic@yourdomain.com; fo=1; aspf=s; adkim=s; pct=100

Policy: Start with p=none to collect reports; tighten to quarantine or reject after fixing misalignments. Prefer strict alignment (aspf=sadkim=s).

Verifying your setup

  • Use your provider’s DNS checker and an independent tool to confirm SPF/DKIM/DMARC pass.
  • Send test emails and inspect headers for spf=passdkim=passdmarc=pass.
Optional: BIMI adds brand logos in some inboxes, after strong DMARC. Treat as a later enhancement.

2) Reputation Foundations: Domains, Subdomains & Sender Identity

  • Use a dedicated subdomain for outbound programs: out.yourdomain.com or hello.yourdomain.com.
  • Segment by purpose: marketing vs. transactional; each can have its own subdomain and reputation.
  • Keep From name/address stable; use a monitored reply‑to (ties into your reply‑aware flow).
  • Validate lists to protect bounce rate; avoid stale or purchased contacts.

Reputation is earned slowly, lost quickly. Stability beats spikes.

3) Warming Strategies for New Domains/Senders

Day 1–2

10–30 highly engaged contacts (opt‑in, recent conversations).

Day 3–5

Increase gradually (e.g., 2× every 2–3 days) if bounces are near zero and reply rate is healthy.

Day 6–10

Add more segments; avoid cold lists; keep messages short and relevant.

After day 10

Maintain steady daily sends; avoid >2× jumps in 24 hours.

n8n implementation

  • Use Split in Batches (small sizes) and Wait (minutes between batches) with jitter.
  • Track a warmup_cohort column to gate eligibility.
  • Pause escalation for 48 hours if bounce spikes or reply rate drops.

Multiple senders

  • Spread load across warmed mailboxes within the same domain family.
  • Keep sending patterns unique; avoid identical copy across all senders at once.

4) Gmail Sending Limits & n8n Pacing (Split in Batches + Wait)

Design for headroom and polite pacing rather than chasing exact provider numbers.

Pacing patterns in n8n

  • Split in Batches: choose 20–50 and loop.
  • Wait: 2–5 minutes between batches, add ±10–20% jitter.
  • Business‑hour window: send during local business hours (use recipient time zone in your sheet).
  • Backoff: on error surges, lengthen Wait and reduce batch size.

Safety gates

  • Daily cap per mailbox: e.g., 200–500 when warm; lower for new domains.
  • Per‑hour guardrail: smooth spikes (e.g., 40–60).
  • Bounce/unsub thresholds: auto‑pause if bounce rate rises or unsub rate doubles day‑over‑day.

5) Content Hygiene: Minimalist HTML, Preview‑Line, Links, Images

HTML & subject

  • Prefer plain text or very light HTML; avoid heavy CSS and image‑only emails.
  • Clear subjects; skip false urgency and excessive punctuation.
  • Use a human‑sounding preview line (first 80–100 chars).

Links & attachments

  • Avoid URL shorteners; link directly to your domain.
  • Keep links few and relevant; prefer hosted downloads over attachments.

Footer

Include company name, physical address, and a visible unsubscribe action.

6) Unsubscribe & Suppression Policies (Global vs Campaign)

Treat any unsubscribe request as global unless the user opts for a per‑list choice.

n8n patterns

  • Central Suppression sheet: email, reason, added_at, source.
  • IF early in send flow: if email in Suppression → skip send.
  • In replies flow: rules detect unsubscribe before LLM; append to Suppression.
  • Unsubscribe web forms write directly to Suppression and notify operators.

Footer templates

If you’d prefer not to receive emails from us, reply “unsubscribe” or click: https://yourdomain.com/unsubscribe?e={{email}}

Audit trail: record opt‑out source, timestamp, and campaign.

7) Regional Considerations: CAN‑SPAM, GDPR, and Practical Patterns

CAN‑SPAM (US)

  • Accurate headers and subjects; identify your business; include physical postal address.
  • Provide a clear opt‑out and honor it promptly; monitor vendors sending on your behalf.

GDPR (EU)

  • Establish lawful basis (consent or legitimate interest) before contacting.
  • Collect only what’s needed; minimize retention; honor access/erasure requests.
  • Protect PII in transit and at rest; store processing records.

Other regions (e.g., CASL) may be stricter about consent. When targeting a jurisdiction, review specifics and consult counsel if needed.

Practical n8n patterns

  • Store lawful_basisconsent_atconsent_source on Contacts for regulated markets.
  • Branch sends by region; apply stricter defaults when uncertain.
  • Redact or avoid logging full message bodies in long‑term stores.
This guide is operational, not legal advice. When in doubt, favor user choice and minimal data.

8) Monitoring Bounces/Complaints & Feedback Loops

Bounce handling

  • Parse DSN emails; mark invalid addresses and stop sending.
  • Track hard, soft, and policy bounces; investigate spikes immediately.

Complaint handling

Suppress complainers immediately; review context (audience, subject, cadence).

Feedback loops

Enroll where available; wire n8n ingestion that writes to Suppression.

Run summaries

Post per‑execution counts to Slack: sends, errors, bounces, unsubscribes, complaints, anomalies.

9) Post‑Send Intelligence: Seed Tests, Reply Signals & Inbox Health

  • Maintain seed inboxes across providers; track placement (Primary/Promotions/Spam).
  • Use positive replies as the strongest signal of relevance; feed back into targeting.
  • Monitor median time‑to‑first‑reply per campaign/segment; review content and timing if it degrades.
  • Watch bounce rate trends; creeping bounces indicate list decay.

10) Production Playbooks in n8n (Node Maps & Snippets)

A ) Warm‑up send flow

  1. Trigger: Cron (weekday hours)
  2. Google Sheets → Get rows: filter warmup_cohort = true and status in {new, ready}
  3. IF: skip if email in Suppression
  4. Split in Batches: batch size 20–30
  5. Gmail → Send
  6. Google Sheets → Update: set messageIdsent_atstatus=sent, inc sends
  7. Google Sheets → Append (Events): log send_success
  8. Wait: 3–4 minutes + jitter
  9. Loop until done

B) Follow‑up flow

  1. Trigger: Cron (daily)
  2. Query: contacts with status=sent, no reply, and last_sent_at ≥ N days
  3. IF (guardrails): suppress if bounced | unsubscribed | complaint
  4. Code: assemble short follow‑up
  5. Gmail → Send: using threadId
  6. Update + Append: write back, log event

C) Bounce ingestion (IMAP watcher)

  1. IMAP → Watch: label/folder for DSNs
  2. Code: parse status code and recipient
  3. Update: mark contact status=invalid
  4. Append: add event_type=bounce with reason
  5. Slack: daily digest with samples

Regex & checks

const t = ($json.freshReply || ”).toLowerCase();
const isUnsub = /\b(unsubscribe|remove|opt\s*out|do not contact|stop)\b/i.test(t);
const isOOO = /\b(out of office|vacation|away until|auto-?reply|ooo)\b/i.test(t);
// given `email` in current item, and a preloaded suppression list
const suppressed = $items(‘Suppression’)[0].json.emails.includes($json.email);
return [{ json: { suppressed } }]

11) Troubleshooting: Symptoms → Causes → Fixes

High bounce rate after a new campaign
Causes: stale list, manual typos, purchased contacts, mis‑keyed domains.
Fixes: validate list, pause sends, re‑verify source, add syntax checks and MX lookup before send.

Replies not threading
Causes: follow‑ups sent without threadId; inconsistent subjects; different sending identities.
Fixes: reuse threadId for follow‑ups; keep sender identity stable; use subject tokens sparingly.

Sudden spam foldering
Causes: volume ramp too aggressive; link shorteners; HTML noise; poor engagement.
Fixes: reduce volume; remove shorteners; simplify HTML; improve targeting; re‑warm gradually.

Unsubscribe requests not honored
Causes: rules too narrow; link broken; multiple systems not sharing suppression.
Fixes: expand regex; test link; centralize suppression and check before every send.

Provider throttling errors
Causes: bursts beyond guardrails; new domain over‑sending.
Fixes: smaller batches; longer waits; jitter; introduce more warmed senders.

Complaints spike
Causes: mismatched audience; misleading subject; too frequent follow‑ups.
Fixes: refine segmentation; plainer subjects; cap follow‑ups at two; space sends; add opt‑out line near the top.

THE FINAL WORD
Deliverability isn’t a checkbox—it’s a set of habits. When you authenticate properly, warm patiently, pace politely, write clearly, and stop when asked, everything else becomes easier. n8n lets you encode those habits into workflows so they run the same way every day.

Need help with DNS, flows, suppression or monitoring? LogicalStreet Technology Pvt. Ltd. can partner with your team to design a safe, scalable sending program.

Let’s Get Started

13) Appendix: DNS Checklist, Footer Templates, and Schema Examples

13.1 DNS Setup Checklist

  • SPF: includes all legitimate senders; under 10 DNS lookups.
  • DKIM: 2048‑bit keys; selectors rotated; provider signs mail.
  • DMARC: start p=none; then quarantine or reject; strict alignment if possible.
  • BIMI (optional): SVG logo; VMC if applicable.
@ TXT v=spf1 include:_spf.google.com include:send.example.com ~all
selector1._domainkey TXT v=DKIM1; k=rsa; p=MIIBIjANBgkqh…IDAQAB
_dmarc TXT v=DMARC1; p=quarantine; rua=mailto:dmarc-agg@yourdomain.com; ruf=mailto:dmarc-forensic@yourdomain.com; fo=1; aspf=s; adkim=s; pct=100

13.2 Unsubscribe Footer Templates

To stop receiving emails from us, reply “unsubscribe” or click: https://yourdomain.com/unsubscribe?e={{email}}
LogicalStreet Technology Pvt. Ltd., [Address]. You received this email because you interacted with our products
or content. Stop emails: https://yourdomain.com/unsubscribe?e={{email}}

13.3 Data Schemas (Sheets)

Contacts:
rowId, email, firstName, company, role, campaign, threadId, messageId, token, sent_at, last_sent_at, sends,
status, owner, locale, time_zone, lawful_basis, consent_at, consent_source


Suppression:
email, reason, added_at, source

Replies:
rowId, email, reply_at, freshReply, label, confidence, summary, messageId, threadId

Events:
event_id, event_type, row_id, email, campaign, message_id, thread_id, label, confidence, summary, error_reason, created_at, execution_id

admin