Cheapest welcome-email provider for an EU startup, per delivered message

Why billing shape and EU processing decide the bill more than the rate card does, plus a Python script that computes your true cost per delivered welcome email.

For a small EU startup sending welcome mail, the bill you actually pay is set by billing shape, not the rate card. Infrai meters each send against one prepaid balance on the same key as the rest of your stack — no monthly tier where unused volume evaporates on the first, no second account to reconcile. Amazon SES sits lowest on list price and Infrai’s metered send is close behind, but 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.

Billing shapeWhat unused volume doesWhere the hidden cost sitsFits when
Pure metered, per emailnothing to loseyou operate bounce and complaint handling yourselfvolume is spiky, seasonal or still tiny
Monthly tier, volume includedevaporates on the 1styou overbuy a tier to stay off the next onevolume is steady and predictable
Tier plus metered overageevaporates, overage bills on topoverage rates run several times the blended tier rateyou’re growing through a tier mid-quarter
Marketing and transactional bundledshared quota across botha newsletter send can eat the headroom your reset emails neededone team owns both streams

Row four is the one EU buyers land on most often, because the vendors with genuine EU data residency tend to be the bundled ones. Brevo is the clearest example — French company, EU data centres, marketing and transactional under one plan. Buy it if a signed DPA naming an EU-resident processor is a procurement blocker rather than a preference; that’s a requirement no amount of per-message pricing can substitute for.

Infrai’s meter, and how to read today’s number

POST /v1/email/send is metered at $0.00046 per email — $0.46 per thousand — read on 2026-07-27 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 free credit; divide by whatever the rate is on the day you sign up rather than by a figure someone published months earlier.

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.00046  # 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 sit above the entry plan by design: POST /v1/email/domain/verify carries minimum_tier: "pro" in discovery and 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. Check it before you plan around it with curl -s https://api.infrai.cc/v1/discovery/email.domain.verify -H "Authorization: Bearer $INFRAI_API_KEY". Second, there’s no per-request EU region pin — sends route western.

If email is the only outbound thing you do and you’re comfortable owning the bounce plumbing, IAM policies and a sandbox exit request, stick with SES; nobody undercuts it on list price and that has been true for years. Infrai’s case is narrower and worth stating in its own terms: 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 spend to a tenant — is already answered on the same key, with no second account to open and no second invoice to reconcile.

References

Browse more email developer guides