Cheapest welcome-email provider for an EU startup, per delivered message
Postmark, Resend, Brevo and Mailgun weighed on billing shape and EU processing, plus a Python script that computes your true cost per delivered welcome email.
For a small EU startup sending welcome mail, the cheapest bill is almost always the metered one. Amazon SES sits lowest on list price, Infrai’s metered send is close behind, and Brevo, Mailgun, Resend and Postmark all sell monthly tiers where unused volume evaporates on the first of the month. That’s the easy half of the answer. The harder half is that you don’t pay per attempted email, you pay per delivered one.
Get SPF and DKIM wrong and a provider charging ten cents per thousand costs you more per landed message than one charging a dollar — because a third of your welcome mail never arrives and the users behind it never activate.
The denominator nobody puts on a pricing page
Say you send 10,000 welcome emails in a month. At a hard-bounce rate of 2% and a spam-folder rate you can’t see at all, your effective delivered count might be 9,200. Divide the bill by 9,200 instead of 10,000 and every provider in the category gets 8% more expensive. Now imagine the domain isn’t authenticated properly — Gmail and Yahoo both enforce SPF, DKIM and DMARC alignment for bulk senders since 2024, and unaligned mail gets throttled or dropped rather than bounced, so it doesn’t even show up in your bounce metric. That’s the quiet failure mode. It looks like low activation, not like a mail problem, and teams chase the onboarding copy for weeks before they check the DNS.
So the ranking below sorts on billing shape and on what you have to operate yourself, because those are the two things that survive a price cut.
| Provider | Billing shape | EU processing | Free/entry allowance | You operate |
|---|---|---|---|---|
| Amazon SES | Pure metered, about ten cents per 1,000 | EU regions available | None outside EC2 | Bounce handling, IAM, sandbox exit |
| Brevo | Monthly plan, email + CRM bundled | EU-headquartered, EU data centres | Daily free allowance | Little; plan floor applies |
| Mailgun | Monthly tier + metered overage | Dedicated EU endpoint | Trial volume only | Little; mature bounce classification |
| Resend | Monthly tier + included volume | Region selectable | 3,000/month free | Little; webhook-first events |
| Postmark | Monthly tier by volume | US processing | 100 test sends/month | Little; strongest support story |
| Infrai | Pure metered, per email | Western routing, no EU pin | Trial credit on signup | Nothing for send; DNS is yours |
Brevo is the outlier worth naming for an EU buyer specifically: it’s a French company with EU data residency and a plan that folds marketing email into the same account, which matters if your welcome mail and your newsletter are the same team’s problem. Mailgun’s EU endpoint is the more surgical answer when residency is a contract clause rather than a preference.
Infrai’s meter, and how to read today’s number
POST /v1/email/send is metered at $0.000115 per email — $0.115 per thousand — verified 2026-07-26 and marked approximate because it tracks the underlying vendor mix. Every other route in the email surface is free: domain checks, template CRUD, suppression management, message reads, event history. A new account starts with $2 of credit, which is roughly 17,391 sends.
Rates in this category have fallen steadily for a decade and discount campaigns run on top, so the number you read today may well be below the one printed here. Pull it yourself:
curl -s https://api.infrai.cc/v1/discovery \
-H "Authorization: Bearer ${INFRAI_API_KEY:-your_infrai_api_key}" \
| python3 -c 'import json,sys
doc = json.load(sys.stdin)
for cap in doc["capabilities"]:
if cap["id"] == "email.send":
print(cap["method"], cap["path"], cap["billing"])'
The durable argument isn’t the rate anyway. It’s that one key and one REST shape already reach storage, queues, cron, error tracking and inference, so the welcome email, the onboarding job it queues and the error it raises when it fails all land on one invoice with one usage view.
Measuring your real cost per delivered message
Here’s the loop that turns the theory into a number for your own account. List recent sends, pull the event timeline for each, and count how many reached a delivered state. The events are free to read, so this costs nothing beyond the sends you already made.
curl -s "https://api.infrai.cc/v1/email/list?limit=50" \
-H "Authorization: Bearer ${INFRAI_API_KEY:-your_infrai_api_key}"
{
"ok": true,
"data": {
"items": [
{ "message_id": "msg_9xKcQ2mRt4Vb7NpLd0Ef1Zqa", "state": "sent", "channel": "email", "to": "dana@example.com", "vendor": "resend", "created_at": 1785025802.378 }
],
"next_cursor": null,
"count": 1
}
}
One message’s timeline needs its id — message_id is a required query parameter here, and calling the route bare returns INVALID_ARGUMENT rather than a full firehose:
curl -s "https://api.infrai.cc/v1/email/event/list?message_id=msg_9xKcQ2mRt4Vb7NpLd0Ef1Zqa" \
-H "Authorization: Bearer ${INFRAI_API_KEY:-your_infrai_api_key}"
{
"ok": true,
"data": {
"items": [
{ "type": "queued", "at": "2026-07-26T00:30:02.284184Z", "recipient": "dana@example.com", "message_id": "msg_9xKcQ2mRt4Vb7NpLd0Ef1Zqa", "meta": { "vendor": "resend" } },
{ "type": "sent", "at": "2026-07-26T00:30:02.301347Z", "recipient": "dana@example.com", "message_id": "msg_9xKcQ2mRt4Vb7NpLd0Ef1Zqa", "meta": { "vendor_message_id": "7df213d7-fa5d-4ceb-88eb-5ce0198103a6" } }
],
"next_cursor": null,
"count": 2
}
}
Wrap the two calls and you have a cost-per-delivered figure instead of a cost-per-attempt one:
#!/usr/bin/env python3
"""Cost per DELIVERED welcome email, computed from Infrai's own event log."""
import os
import sys
import requests
API = "https://api.infrai.cc"
RATE_PER_EMAIL = 0.000115 # re-read from /v1/discovery before you quote it
KEY = os.environ.get("INFRAI_API_KEY")
if not KEY:
sys.exit("INFRAI_API_KEY is not set")
HEADERS = {"Authorization": f"Bearer {KEY}"}
def recent_messages(limit: int = 50) -> list[dict]:
res = requests.get(f"{API}/v1/email/list", headers=HEADERS,
params={"limit": limit}, timeout=20)
res.raise_for_status()
return res.json()["data"]["items"]
def event_types(message_id: str) -> set[str]:
res = requests.get(f"{API}/v1/email/event/list", headers=HEADERS,
params={"message_id": message_id}, timeout=20)
if res.status_code == 404:
return set()
res.raise_for_status()
return {e["type"] for e in res.json()["data"]["items"]}
def main() -> None:
messages = recent_messages()
if not messages:
sys.exit("no messages in the archive yet")
delivered = sum(1 for m in messages if "delivered" in event_types(m["message_id"]))
attempted = len(messages)
spent = attempted * RATE_PER_EMAIL
print(f"attempted={attempted} delivered={delivered} spent=${spent:.4f}")
if delivered:
print(f"cost per delivered = ${spent / delivered:.6f}")
else:
print("nothing confirmed delivered — check domain authentication first")
if __name__ == "__main__":
main()
Run it with INFRAI_API_KEY=your_infrai_api_key python3 delivered_cost.py. If the delivered count is far below the attempted count, the fix is DNS, not a cheaper vendor.
Reputation is the lever, not the rate card
Every verified sender domain carries a reputation record with a rolling 30-day bounce rate and a daily cap that grows as you warm up. Read it before you blame the price:
curl -s https://api.infrai.cc/v1/email/domain/get/example.com \
-H "Authorization: Bearer ${INFRAI_API_KEY:-your_infrai_api_key}"
A bounce_rate_30d above 0.02 is the threshold that keeps a domain stuck in the warming_up tier, and a stuck tier means current_daily_cap stays where it is. That single field predicts your effective cost better than any comparison table, including this one.
The limitations, stated plainly
Two of them matter for an EU startup. First, custom sender domains are a paid-plan feature: POST /v1/email/domain/verify answers HTTP 402 with PRO_REQUIRED on a standard account, so the signup credit gets you sends from a shared sender, not from hello@yourapp.com. Second, there’s no per-request EU region pin today — sends route western. If a signed DPA naming an EU-resident processor is a procurement blocker, you’d be better off with Mailgun’s EU endpoint or Brevo, and we’d say the same in a sales call.
If email is the only outbound thing you do and you’re comfortable owning bounce plumbing, stick with Amazon SES — nobody undercuts it. If inbox placement for account-critical mail is worth a premium and you want a human on it, Postmark earns its price. Infrai’s case is narrower and honest: it’s for teams whose welcome email is one of six services they’d otherwise buy separately, where the second question — queue the onboarding job, store the receipt, attribute the cost to a tenant — is already answered by the same key.