{"id":"69bb38f63f1c7d8bc1820a11","title":"Brevo Email","path":"how-to/technical-articles/2026-03-18-single-instance-multi-tenant-exploration/brevo-email","contentMarkdown":"# Email at Scale: Outbound via Brevo, Inbound via Cloudflare\n\n_____\n\nFrom Ramblers Head Office's perspective, the most immediately deployable capability across groups is **email**. This article covers both the outbound and inbound email architecture, their design philosophy, and what multi-tenant email at 500 groups would require.\n\n## What Groups Receive Today\n\nGroups already on the NGX Ramblers platform receive a complete email solution covering both directions:\n\n**Outbound (via Brevo):**\n- Newsletter and bulk email sending\n- Event notification emails (new events, changes, cancellations)\n- Booking confirmation, cancellation, and waitlist emails\n- Member welcome and renewal reminder emails\n- Configurable email templates and sender identity per group\n\n**Inbound (via Cloudflare Email Routing):**\n- Role-based email addresses (e.g. `chairman@group-a-ramblers.org.uk`, `events@group-a-ramblers.org.uk`)\n- Single-recipient forwarding to a committee member's personal email\n- Multi-recipient forwarding via Cloudflare Workers (e.g. `secretary@` forwards to 3 committee members simultaneously)\n- Catch-all routing for unmatched addresses\n- Destination address verification to prevent misuse\n- SPF, DKIM, and DMARC validation on all inbound mail\n- Full email routing logs with 30-day audit trail\n- Admin UI for managing all routing rules, destinations, and workers\n\n## Outbound Email Architecture\n\nBrevo handles all outbound email. This was an intentional design decision: the platform was built to operate within Brevo's free account tier, which covers outbound sending. However, the Brevo integration is extensible — any additional Brevo capabilities (inbound email parsing, marketing automation, transactional webhooks, etc.) could be integrated into the platform if a paid Brevo plan were adopted.\n\n```mermaid\nflowchart LR\n    subgraph ngx[\"NGX Ramblers\"]\n        ADMIN@{ icon: \"ngx:user\", label: \"Group admin\", pos: \"b\", h: 48 }\n        EMAIL[\"Outbound Email Service<br/>group-scoped\"]\n        ADMIN --> EMAIL\n    end\n\n    subgraph brevo[\"Brevo\"]\n        SEND@{ icon: \"ngx:brevo\", label: \"Brevo API\", pos: \"b\", h: 48 }\n        TPL[\"Templates per group\"]\n        LIST[\"Contact lists per group\"]\n    end\n\n    EMAIL --> SEND\n    SEND --> TPL\n    SEND --> LIST\n    LIST -->|\"newsletters\"| M1@{ icon: \"ngx:user\", label: \"Members\", pos: \"b\", h: 48 }\n    LIST -->|\"event notifications\"| M1\n    LIST -->|\"booking confirmations\"| M1\n\n    style ngx fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143\n    style brevo fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143\n```\n\n## Inbound Email Architecture\n\nCloudflare Email Routing handles all inbound email with sophisticated per-role forwarding. This is fully managed through the NGX Ramblers admin UI — no Cloudflare dashboard access required.\n\n### How It Works\n\nEach committee role (chairman, secretary, events coordinator, etc.) gets a dedicated email address on the group's domain. The admin configures where each address forwards to:\n\n- **Single recipient** — a direct Cloudflare routing rule forwards to one personal email\n- **Multiple recipients** — a Cloudflare Worker script is deployed that forwards to all recipients simultaneously\n- **Catch-all** — a fallback rule captures any unmatched addresses\n\n```mermaid\nflowchart TD\n    SENDER@{ icon: \"ngx:user\", label: \"External sender\", pos: \"b\", h: 48 }\n    SENDER -->|\"chairman@group-a-ramblers.org.uk\"| CF\n\n    subgraph CF[\"Cloudflare Email Routing\"]\n        CFI@{ icon: \"ngx:cloudflare\", label: \"Cloudflare\", pos: \"b\", h: 48 }\n        CFI --> MATCH[\"Rule matcher<br/>literal match on To address\"]\n        MATCH -->|\"single recipient\"| DIRECT[\"Direct forward rule\"]\n        MATCH -->|\"multiple recipients\"| WORKER[\"Cloudflare Worker<br/>email-fwd-group-a-chairman\"]\n        MATCH -->|\"no match\"| CATCH[\"Catch-all rule\"]\n    end\n\n    DIRECT -->|\"forward\"| R1@{ icon: \"ngx:user\", label: \"Committee member\", pos: \"b\", h: 48 }\n    WORKER -->|\"forward to all\"| R2@{ icon: \"ngx:user\", label: \"Recipient 1\", pos: \"b\", h: 48 }\n    WORKER -->|\"forward to all\"| R3@{ icon: \"ngx:user\", label: \"Recipient 2\", pos: \"b\", h: 48 }\n    WORKER -->|\"forward to all\"| R4@{ icon: \"ngx:user\", label: \"Recipient 3\", pos: \"b\", h: 48 }\n    CATCH -->|\"fallback\"| R5@{ icon: \"ngx:user\", label: \"Secretary\", pos: \"b\", h: 48 }\n\n    style CF fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143\n```\n\n### Admin UI Capabilities\n\nThe NGX Ramblers admin interface provides full control over email routing without needing Cloudflare dashboard access:\n\n- **Per-role configuration** — select forwarding target (member email, custom address, or multiple recipients) for each committee role\n- **Destination verification** — register and verify forwarding addresses via Cloudflare's email confirmation flow\n- **Worker management** — deploy, update, and delete multi-recipient Worker scripts directly from the admin UI\n- **Status monitoring** — real-time status badges showing ACTIVE, OUTDATED, MISSING, or PENDING for each role's forwarding\n- **Orphan detection** — identifies deployed Worker scripts not linked to any routing rule\n- **Email routing logs** — 30-day rolling audit trail showing all routed emails with SPF/DKIM/DMARC validation results\n- **Worker invocation logs** — execution monitoring for multi-recipient Workers (requests, errors, subrequests)\n\n### Authentication and Deliverability\n\nAll inbound email passes through Cloudflare's authentication pipeline:\n\n- **SPF** (Sender Policy Framework) — validates the sending server is authorised\n- **DKIM** (DomainKeys Identified Mail) — validates the message hasn't been tampered with\n- **DMARC** (Domain-based Message Authentication) — policy enforcement combining SPF and DKIM\n\nAuthentication results are logged and visible in the admin UI, helping diagnose deliverability issues.\n\n## Complete Email Flow — Both Directions\n\n**Outbound** (platform to members): NGX Ramblers → Brevo API → member inboxes\n\n**Inbound** (public to committee): external sender → Cloudflare Email Routing → committee member inboxes\n\n**Admin**: all routing rules, destinations, and logs managed through the NGX Ramblers admin UI — no Cloudflare dashboard access required\n\n## Multi-Tenant Email Requirements at 500 Groups\n\nFor a national rollout, the multi-tenant architecture must prioritise:\n\n1. **Per-group Brevo configuration** — each group needs its own sender identity, templates, and contact lists\n2. **Email isolation** — Group A's member list must never receive Group B's emails\n3. **Shared Brevo account vs per-group accounts** — a single Brevo organisation with sub-accounts, or a centralised account with list-level segregation\n4. **Deliverability at scale** — SPF, DKIM, and DMARC records per group domain to maintain inbox placement across 500 sending domains\n5. **Cloudflare email routing per group** — each group needs its own set of routing rules and verified destinations. Currently each group has its own Cloudflare zone — in a multi-tenant model, this could be managed centrally via the super-admin concept\n6. **Inbound routing at scale** — in practice, most groups use a single contact address forwarding to one person via a simple Cloudflare routing rule (no Worker required). Multi-recipient Workers are available for groups that need them but are the exception rather than the norm. This means scaling to 500 groups is primarily a matter of managing simple routing rules, not thousands of Worker scripts\n","contentHtml":"<h1>Email at Scale: Outbound via Brevo, Inbound via Cloudflare</h1>\n<hr>\n<p>From Ramblers Head Office&#39;s perspective, the most immediately deployable capability across groups is <strong>email</strong>. This article covers both the outbound and inbound email architecture, their design philosophy, and what multi-tenant email at 500 groups would require.</p>\n<h2>What Groups Receive Today</h2>\n<p>Groups already on the NGX Ramblers platform receive a complete email solution covering both directions:</p>\n<p><strong>Outbound (via Brevo):</strong></p>\n<ul>\n<li>Newsletter and bulk email sending</li>\n<li>Event notification emails (new events, changes, cancellations)</li>\n<li>Booking confirmation, cancellation, and waitlist emails</li>\n<li>Member welcome and renewal reminder emails</li>\n<li>Configurable email templates and sender identity per group</li>\n</ul>\n<p><strong>Inbound (via Cloudflare Email Routing):</strong></p>\n<ul>\n<li>Role-based email addresses (e.g. <code>chairman@group-a-ramblers.org.uk</code>, <code>events@group-a-ramblers.org.uk</code>)</li>\n<li>Single-recipient forwarding to a committee member&#39;s personal email</li>\n<li>Multi-recipient forwarding via Cloudflare Workers (e.g. <code>secretary@</code> forwards to 3 committee members simultaneously)</li>\n<li>Catch-all routing for unmatched addresses</li>\n<li>Destination address verification to prevent misuse</li>\n<li>SPF, DKIM, and DMARC validation on all inbound mail</li>\n<li>Full email routing logs with 30-day audit trail</li>\n<li>Admin UI for managing all routing rules, destinations, and workers</li>\n</ul>\n<h2>Outbound Email Architecture</h2>\n<p>Brevo handles all outbound email. This was an intentional design decision: the platform was built to operate within Brevo&#39;s free account tier, which covers outbound sending. However, the Brevo integration is extensible — any additional Brevo capabilities (inbound email parsing, marketing automation, transactional webhooks, etc.) could be integrated into the platform if a paid Brevo plan were adopted.</p>\n<pre><code class=\"language-mermaid\">flowchart LR\n    subgraph ngx[&quot;NGX Ramblers&quot;]\n        ADMIN@{ icon: &quot;ngx:user&quot;, label: &quot;Group admin&quot;, pos: &quot;b&quot;, h: 48 }\n        EMAIL[&quot;Outbound Email Service&lt;br/&gt;group-scoped&quot;]\n        ADMIN --&gt; EMAIL\n    end\n\n    subgraph brevo[&quot;Brevo&quot;]\n        SEND@{ icon: &quot;ngx:brevo&quot;, label: &quot;Brevo API&quot;, pos: &quot;b&quot;, h: 48 }\n        TPL[&quot;Templates per group&quot;]\n        LIST[&quot;Contact lists per group&quot;]\n    end\n\n    EMAIL --&gt; SEND\n    SEND --&gt; TPL\n    SEND --&gt; LIST\n    LIST --&gt;|&quot;newsletters&quot;| M1@{ icon: &quot;ngx:user&quot;, label: &quot;Members&quot;, pos: &quot;b&quot;, h: 48 }\n    LIST --&gt;|&quot;event notifications&quot;| M1\n    LIST --&gt;|&quot;booking confirmations&quot;| M1\n\n    style ngx fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143\n    style brevo fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143\n</code></pre>\n<h2>Inbound Email Architecture</h2>\n<p>Cloudflare Email Routing handles all inbound email with sophisticated per-role forwarding. This is fully managed through the NGX Ramblers admin UI — no Cloudflare dashboard access required.</p>\n<h3>How It Works</h3>\n<p>Each committee role (chairman, secretary, events coordinator, etc.) gets a dedicated email address on the group&#39;s domain. The admin configures where each address forwards to:</p>\n<ul>\n<li><strong>Single recipient</strong> — a direct Cloudflare routing rule forwards to one personal email</li>\n<li><strong>Multiple recipients</strong> — a Cloudflare Worker script is deployed that forwards to all recipients simultaneously</li>\n<li><strong>Catch-all</strong> — a fallback rule captures any unmatched addresses</li>\n</ul>\n<pre><code class=\"language-mermaid\">flowchart TD\n    SENDER@{ icon: &quot;ngx:user&quot;, label: &quot;External sender&quot;, pos: &quot;b&quot;, h: 48 }\n    SENDER --&gt;|&quot;chairman@group-a-ramblers.org.uk&quot;| CF\n\n    subgraph CF[&quot;Cloudflare Email Routing&quot;]\n        CFI@{ icon: &quot;ngx:cloudflare&quot;, label: &quot;Cloudflare&quot;, pos: &quot;b&quot;, h: 48 }\n        CFI --&gt; MATCH[&quot;Rule matcher&lt;br/&gt;literal match on To address&quot;]\n        MATCH --&gt;|&quot;single recipient&quot;| DIRECT[&quot;Direct forward rule&quot;]\n        MATCH --&gt;|&quot;multiple recipients&quot;| WORKER[&quot;Cloudflare Worker&lt;br/&gt;email-fwd-group-a-chairman&quot;]\n        MATCH --&gt;|&quot;no match&quot;| CATCH[&quot;Catch-all rule&quot;]\n    end\n\n    DIRECT --&gt;|&quot;forward&quot;| R1@{ icon: &quot;ngx:user&quot;, label: &quot;Committee member&quot;, pos: &quot;b&quot;, h: 48 }\n    WORKER --&gt;|&quot;forward to all&quot;| R2@{ icon: &quot;ngx:user&quot;, label: &quot;Recipient 1&quot;, pos: &quot;b&quot;, h: 48 }\n    WORKER --&gt;|&quot;forward to all&quot;| R3@{ icon: &quot;ngx:user&quot;, label: &quot;Recipient 2&quot;, pos: &quot;b&quot;, h: 48 }\n    WORKER --&gt;|&quot;forward to all&quot;| R4@{ icon: &quot;ngx:user&quot;, label: &quot;Recipient 3&quot;, pos: &quot;b&quot;, h: 48 }\n    CATCH --&gt;|&quot;fallback&quot;| R5@{ icon: &quot;ngx:user&quot;, label: &quot;Secretary&quot;, pos: &quot;b&quot;, h: 48 }\n\n    style CF fill:#E8F5EE,stroke:#9BC8AB,stroke-width:2px,rx:12,ry:12,color:#404143\n</code></pre>\n<h3>Admin UI Capabilities</h3>\n<p>The NGX Ramblers admin interface provides full control over email routing without needing Cloudflare dashboard access:</p>\n<ul>\n<li><strong>Per-role configuration</strong> — select forwarding target (member email, custom address, or multiple recipients) for each committee role</li>\n<li><strong>Destination verification</strong> — register and verify forwarding addresses via Cloudflare&#39;s email confirmation flow</li>\n<li><strong>Worker management</strong> — deploy, update, and delete multi-recipient Worker scripts directly from the admin UI</li>\n<li><strong>Status monitoring</strong> — real-time status badges showing ACTIVE, OUTDATED, MISSING, or PENDING for each role&#39;s forwarding</li>\n<li><strong>Orphan detection</strong> — identifies deployed Worker scripts not linked to any routing rule</li>\n<li><strong>Email routing logs</strong> — 30-day rolling audit trail showing all routed emails with SPF/DKIM/DMARC validation results</li>\n<li><strong>Worker invocation logs</strong> — execution monitoring for multi-recipient Workers (requests, errors, subrequests)</li>\n</ul>\n<h3>Authentication and Deliverability</h3>\n<p>All inbound email passes through Cloudflare&#39;s authentication pipeline:</p>\n<ul>\n<li><strong>SPF</strong> (Sender Policy Framework) — validates the sending server is authorised</li>\n<li><strong>DKIM</strong> (DomainKeys Identified Mail) — validates the message hasn&#39;t been tampered with</li>\n<li><strong>DMARC</strong> (Domain-based Message Authentication) — policy enforcement combining SPF and DKIM</li>\n</ul>\n<p>Authentication results are logged and visible in the admin UI, helping diagnose deliverability issues.</p>\n<h2>Complete Email Flow — Both Directions</h2>\n<p><strong>Outbound</strong> (platform to members): NGX Ramblers → Brevo API → member inboxes</p>\n<p><strong>Inbound</strong> (public to committee): external sender → Cloudflare Email Routing → committee member inboxes</p>\n<p><strong>Admin</strong>: all routing rules, destinations, and logs managed through the NGX Ramblers admin UI — no Cloudflare dashboard access required</p>\n<h2>Multi-Tenant Email Requirements at 500 Groups</h2>\n<p>For a national rollout, the multi-tenant architecture must prioritise:</p>\n<ol>\n<li><strong>Per-group Brevo configuration</strong> — each group needs its own sender identity, templates, and contact lists</li>\n<li><strong>Email isolation</strong> — Group A&#39;s member list must never receive Group B&#39;s emails</li>\n<li><strong>Shared Brevo account vs per-group accounts</strong> — a single Brevo organisation with sub-accounts, or a centralised account with list-level segregation</li>\n<li><strong>Deliverability at scale</strong> — SPF, DKIM, and DMARC records per group domain to maintain inbox placement across 500 sending domains</li>\n<li><strong>Cloudflare email routing per group</strong> — each group needs its own set of routing rules and verified destinations. Currently each group has its own Cloudflare zone — in a multi-tenant model, this could be managed centrally via the super-admin concept</li>\n<li><strong>Inbound routing at scale</strong> — in practice, most groups use a single contact address forwarding to one person via a simple Cloudflare routing rule (no Worker required). Multi-recipient Workers are available for groups that need them but are the exception rather than the norm. This means scaling to 500 groups is primarily a matter of managing simple routing rules, not thousands of Worker scripts</li>\n</ol>\n"}