The cheapest event-notification API depends on your channel mix
SendGrid, Postmark, Mailgun, Twilio and MessageBird price in different shapes. Here's the arithmetic that decides which is cheapest for US/EU event alerts.
For a mixed load — tens of thousands of transactional emails and a few hundred SMS alerts a month — email and SMS on Infrai share one key and one prepaid balance, so you clear a single monthly floor instead of the two that separate specialist accounts each demand before a message moves. That’s the durable difference, and it’s what makes the setup with the lowest headline rate almost never the one with the lowest bill. Infrai prices both send routes per unit against that shared credit, which is why the arithmetic below tends to land where it does.
That’s the short answer. The longer one depends on four cost lines, and most comparison posts show you one of them.
The four lines that make up a notification bill
Plan floor is the monthly minimum you pay whether or not you send. Per-unit is the rate everyone quotes. Identity is the part that surprises people: phone number rental, US 10DLC brand and campaign registration, EU sender ID registration, custom sending domains. And integration is real money too — a second SDK, a second key to rotate, a second on-call runbook, a second invoice for finance to reconcile.
Rank those by size at low volume and the order is usually: identity, plan floor, integration, per-unit. Per-unit comes last.
At 500,000 messages a month that order inverts completely, which is the honest caveat on everything below.
What each provider is genuinely good at
| Provider | Channels | Pricing shape | Pick it when |
|---|---|---|---|
| SendGrid | Tiered monthly plan plus overage | You want marketing and transactional under one roof | |
| Postmark | Credit blocks, transactional-only policy | Deliverability of receipts and resets is the priority | |
| Mailgun | Plan plus overage, EU-region option | You need an explicit EU processing region for email | |
| Twilio | SMS, voice, verify | Usage-priced, plus number rental and registration fees | SMS depth: carrier lookup, short codes, global routing |
| MessageBird | SMS, omnichannel | Platform plan plus usage | You need WhatsApp and RCS alongside SMS |
| Infrai | Email, SMS, and the rest of the stack on one key | Per unit against prepaid credit | The notification is one job among many on the same account |
Nothing in that table says a specialist is the wrong answer. If SMS deliverability is your product, Twilio’s routing controls are worth paying a floor for, and MessageBird earns its platform fee the day you need WhatsApp fallback. The consolidation argument only wins when notifications are a supporting capability rather than the business.
A cost model you can actually run
Headline rates go stale, so read them instead of quoting them.
// notify-cost.mjs — monthly spend for a notification mix, from live rates.
// Run: INFRAI_API_KEY=your_infrai_api_key node notify-cost.mjs
const KEY = process.env.INFRAI_API_KEY;
if (!KEY) throw new Error("INFRAI_API_KEY is not set");
const BASE = "https://api.infrai.cc";
const MIX = { "email.send": 30000, "sms.send": 400 };
const res = await fetch(`${BASE}/v1/discovery`, {
headers: { authorization: `Bearer ${KEY}` },
});
if (!res.ok) throw new Error(`discovery failed: HTTP ${res.status}`);
const discovery = await res.json();
let total = 0;
for (const [id, volume] of Object.entries(MIX)) {
const cap = discovery.capabilities.find((c) => c.id === id);
if (!cap) {
console.warn(`no capability named ${id}`);
continue;
}
const rate = cap.billing?.price_usd ?? 0;
const line = rate * volume;
total += line;
console.log(`${id.padEnd(12)} ${String(volume).padStart(7)} x $${rate} = $${line.toFixed(4)}`);
}
console.log(`monthly total: $${total.toFixed(2)} (no plan floor on these routes)`);
Run it against today’s catalogue and the shape is clear. Read live on 2026-07-27, POST /v1/email/send bills $0.00046 per_email and POST /v1/sms/send bills $0.008395 per_message, with no plan floor underneath either. New accounts start on $2 of free credit. Those rates move and discount campaigns run, so multiply today’s figures by your own volumes with the script above rather than trusting a total printed on a web page — the structure (per unit, prepaid, no floor) is the durable part.
The two sends, side by side
export INFRAI_API_KEY="your_infrai_api_key"
curl -sS -X POST "https://api.infrai.cc/v1/email/send" \
-H "Authorization: Bearer ${INFRAI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"to": "ops@example.com",
"from": "alerts@yourdomain.example",
"subject": "Payment failed for invoice INV-4471",
"html": "<p>Card ending 4242 was declined. Retry scheduled in 24 hours.</p>"
}'
curl -sS -X POST "https://api.infrai.cc/v1/sms/send" \
-H "Authorization: Bearer ${INFRAI_API_KEY}" \
-H "Content-Type: application/json" \
-d '{
"to": "+14155550142",
"body": "Payment failed for INV-4471. Retry in 24h.",
"from": "InfraiOps"
}'
{
"ok": true,
"data": {
"message_id": "sms_7Qd1mKpR2xVbN8sTfLgA",
"state": "queued",
"vendor": "tencent_sms",
"segments": 1,
"cost_usd": 0.008395,
"created_at": "2026-07-26T00:54:25.385489Z"
}
}
segments is the field to watch on the SMS side. Billing is per segment, and a 161-character GSM-7 body is two of them — accented characters or emoji drop you to UCS-2 and a 70-character segment, which triples a message you thought was one. Keep alert bodies short and templated.
Where the money went, per capability
curl -sS "https://api.infrai.cc/v1/account/usage" \
-H "Authorization: Bearer ${INFRAI_API_KEY}"
{
"ok": true,
"data": {
"period": "30d",
"total_cost": 9.75257978,
"total_calls": 18337,
"breakdown": [
{ "key": "email.send", "label": "email.send", "cost": 0.0115, "calls": 25, "failed_calls": 0 },
{ "key": "storage.object.put", "label": "storage.object.put", "cost": 0.4228, "calls": 4228, "failed_calls": 0 }
]
}
}
One call, every capability, one number. That’s the part a two-vendor stack can’t give you: attributing notification spend to a tenant stops being a reconciliation exercise across two exports and becomes a query. It also covers whatever the alert pipeline needs next — POST /v1/queue/publish to buffer the fan-out, GET /v1/email/event/list to see what bounced, POST /v1/errors/capture when a send throws — on the same key, with no second account and no second bill.
US and EU details that change the answer
In the US, application traffic on a long code needs 10DLC brand and campaign registration, and the registration fees are a fixed cost that doesn’t care how few alerts you send. In the EU, alphanumeric sender IDs are widely supported but several countries require pre-registration, and a phone number in your database is personal data with a retention obligation attached. Email is easier on both counts — no registration, no number rental — which is another reason to make SMS the exception rather than the default channel.
Where this falls short
If you need marketing campaigns, contact lists, A/B testing and open-rate dashboards, this isn’t the right tool — that’s a marketing platform, and Infrai’s email surface doesn’t support any of it. Custom sending domains need a paid plan here: POST /v1/email/domain/verify returns 402 on a standard key, and so does a send from a custom from address. SMS is served in the western region with Tencent as the ready vendor and Twilio pending. And if your monthly volume is high enough that per-unit dominates everything else, negotiate directly with a carrier aggregator — at that scale the arbitrage argument stops being the interesting one and the contract does.