How to Send Email From Your Own Domain for Free: Cloudflare + Brevo (2026)
A small software team in Bangkok may need [email protected] for partnerships, contact forms, and invoices. A paid mailbox seat runs about THB 220 a month per person -- hard to justify before the channel has real traffic. A five-person team in Ho Chi Minh City hit the same math last quarter: separate receiving from sending.
Quick verdict: use Cloudflare Email Routing to forward incoming mail to an inbox you already check, and Brevo's SMTP relay or API to send authenticated mail from the custom address. Brevo's free plan allows 300 sends a day, though free-plan messages carry Brevo branding -- a minor annoyance, not a dealbreaker. Cloudflare also launched its own outbound Email Service in 2026, worth comparing if you're starting from zero.
No affiliate links appear in this article at publication; if one is added later, it will be visibly disclosed.
The architecture
Incoming: recipient → [email protected] → Cloudflare Email Routing → your verified inbox
Outgoing: your app/CRM → Brevo API or SMTP → recipient's inbox
Cloudflare's routing rule maps an address on your domain to a verified destination. Brevo signs and delivers outgoing mail separately -- keeping the two jobs apart means you can receive replies without buying a hosted mailbox while still authenticating outbound mail correctly.
What this setup costs and what it does not do
| Component | Job | Free-tier reality | Main limitation |
|---|---|---|---|
| Cloudflare Email Routing | Forward incoming mail | Destination must be verified | Forwarding, not a mailbox |
| Brevo transactional email | Send via API or SMTP | 300 sends/day, no time limit | Brevo branding; unused quota doesn't roll over |
| Your existing inbox | Read and reply | Often already paid for | May expose the inbox unless Send mail as is set up |
| DNS authentication | Prove Brevo may send for the domain | Free to configure | A wrong SPF, DKIM, or DMARC record can break delivery |
A .com domain runs about SGD 15-20 a year, the one recurring cost this setup can't avoid. You still need to own the domain, and free allowances can change.
Step 1: route incoming mail with Cloudflare
- Put the domain's DNS on Cloudflare.
- In Compute → Email Service → Email Routing, add the inbox that should receive forwarded mail.
- Open the verification message in that destination inbox.
- Create a routing rule such as
[email protected]→ your verified destination. - Send a test from an unrelated address and confirm that it arrives.
Cloudflare also supports catch-all rules and Workers for advanced processing. Start with one explicit address -- a catch-all pulls in typos and spam along with valid mail.
Step 2: authenticate the domain in Brevo
Add the domain in Brevo's sender and domain area. Copy the DNS values from the dashboard rather than a tutorial, since selectors and verification tokens are account-specific.
- SPF authorizes the sending service -- one TXT record per domain; merge senders into it instead of publishing competing records.
- DKIM gives each message a cryptographic signature receiving servers can verify.
- DMARC tells receivers what to do on failure, and can send reports to an address you control.
Start DMARC monitoring conservatively and tighten the policy only after every legitimate sender is aligned. Jumping straight to rejection can block real invoices or support replies still routed through another service.
Step 3: send through SMTP or the API
Use SMTP when an app only asks for a server, port, username, and password. Use the API for structured errors, message IDs, and webhook events. Teams often treat the two as interchangeable -- they aren't, and the gap shows the first time a send fails silently under SMTP with no error to chase.
Keep the credential in an environment variable or secret manager, never in a repo or browser-side JavaScript. Give each production system its own credential so one integration can be revoked without stopping everything else.
For a no-code workflow, n8n can call Brevo after a qualified form submission; HubSpot can hold the contact record while Freshworks owns replies. A one-person shop in Manila skipped the CRM step and just filtered on a Brevo tag -- fine until they crossed 40 leads a week.
Step 4: make replying from the same address work
Forwarding alone doesn't make your inbox send as [email protected]. If staff need to reply manually from the branded address, configure the inbox provider's Send mail as feature with Brevo's SMTP credentials, then complete verification.
Test the visible From, Reply-To, and Return-Path addresses separately -- a message can look correct in the composer while alignment is still wrong underneath.
Step 5: run a real delivery test
Don't stop when a dashboard says "authenticated." Send a plain-text and an HTML message to two different mailbox providers, check the headers for SPF/DKIM/DMARC results, then confirm a reply reaches the routed inbox.
| Test | Pass condition | If it fails |
|---|---|---|
| Inbound routing | Message reaches the destination inbox | Recheck routing rule and MX records |
| SPF | Header reports SPF pass | Merge the include into the single SPF record |
| DKIM | Header reports DKIM pass | Recheck selector and DNS propagation |
| DMARC | Header reports DMARC pass, aligned | Fix SPF/DKIM alignment first |
| Reply loop | Reply returns to the routed inbox | Inspect From, Reply-To, send-as settings |
Responsible sending checklist
Use this setup for messages people expect -- account notices, follow-ups they requested, support, invoices, permission-based newsletters. It is not permission to scrape addresses or blast a purchased list.
Before sending: identify the sender, use a real reply address, and keep a suppression list. Honor opt-outs promptly, remove bounces and complaints, send small batches until the domain earns a reputation, and follow applicable privacy and anti-spam laws.
Sources and verification
Checked 11 August 2026 against Cloudflare's routing docs, Email Service limits, Brevo's free-plan limits, and Brevo's authentication guide. Free-tier limits change -- confirm current allowances in the dashboard before you rely on them.