Sovereign transactional email · Canada · UK · EU

Sovereign transactional email.
Hosted in Canada. Canadian-owned.

Your recipients' data is stored and processed only in Canada, by a Canadian-owned company with no US parent — and Canada is GDPR-adequate for the EU, UK, and Switzerland. A developer-first REST API and SMTP relay, CASL-compliant out of the box. From $0.15 CAD per 1,000.

Start free — no card required See pricing

Check any domain’s SPF, DKIM and DMARC No signup.

Data residency 🇨🇦 Canada
Ownership 🇨🇦 Canadian
EU / UK / Swiss data GDPR-adequate* *In EU speak, adequate means quite good

Everything you need. Nothing you don't.

Data sovereignty, a clean API, and compliance built in — not bolted on after the fact.

🛡️

Canadian-owned, Canadian-hosted

Hosted in Canada, by a Canadian-owned company with no US parent. A clean, auditable answer for any Canadian, UK, or EU privacy policy.

🔒

Encryption you can require

Mark a key “transport encryption required” and its mail goes out only over TLS 1.2 or better, with a certificate we verify. If a recipient’s server cannot meet that, the message is not sent — and you are told which recipients and why, rather than it quietly going out in the clear.

⚡

REST API + SMTP relay

One endpoint. Bearer token auth. JSON in, JSON out. Or drop in SMTP credentials and send from any existing mailer. First email in under 5 minutes.

🔑

DKIM signing — automatic

Per-domain keypairs generated at signup. Automated DNS verification. Your emails land in inboxes, not spam folders. No shared infrastructure.

📊

Full delivery visibility

Per-message status, bounce rates, complaint rates — all queryable by date range via the API. Know exactly what happened to every email.

🪝

Real-time webhooks

Delivered, bounced, complained — pushed to your endpoint the moment it happens. HMAC-signed for verification. Auto-retry with exponential backoff.

💰

$0.15 CAD per 1,000 emails

5–8× cheaper than Mailgun, SendGrid, or Postmark. No contracts, no minimums, no setup fees. Invoiced monthly. Available in CAD, GBP, EUR, or USD.

🤖

Built for AI agents

A remote MCP server lets your AI agents send email with a scoped API key. Scopes limit what each agent can do; sandbox contains a new key's blast radius. Hand off send power without handing over everything.

For developers

The simplest email API you'll use

One endpoint, or the SMTP settings you already have. Whatever the key decides — sending identity, transport policy, unsubscribe behaviour — applies either way, so there is no second configuration to keep in step.

// Node 18+ — no dependency, fetch is built in
const res = await fetch('https://zedmail.com/v1/email/send', {
  method: 'POST',
  headers: {
    Authorization: `Bearer ${process.env.ZEDMAIL_KEY}`,
    'Content-Type': 'application/json',
  },
  body: JSON.stringify({
    from:    'receipts@boutique.ca',
    to:      'client@example.ca',
    subject: 'Votre reçu',
    html:    '<p>Merci de votre achat.</p>',
    tags:    ['order-4812'],
  }),
});

const { message_id } = await res.json();   // msg_a1b2c3d4e5f6a7b8
<?php
$ch = curl_init('https://zedmail.com/v1/email/send');
curl_setopt_array($ch, [
    CURLOPT_POST           => true,
    CURLOPT_RETURNTRANSFER => true,
    CURLOPT_HTTPHEADER     => [
        'Authorization: Bearer ' . getenv('ZEDMAIL_KEY'),
        'Content-Type: application/json',
    ],
    CURLOPT_POSTFIELDS     => json_encode([
        'from'    => 'receipts@boutique.ca',
        'to'      => 'client@example.ca',
        'subject' => 'Votre reçu',
        'html'    => '<p>Merci de votre achat.</p>',
        'tags'    => ['order-4812'],
    ]),
]);

$res = json_decode(curl_exec($ch), true);
echo $res['message_id'];   // msg_a1b2c3d4e5f6a7b8
# .env — Zedmail is a standard SMTP mailer, so Mailables,
# queues and Mail::fake() all keep working unchanged.

MAIL_MAILER=smtp
MAIL_HOST=mail.zedmail.com
MAIL_PORT=465
MAIL_ENCRYPTION=tls
MAIL_USERNAME="${ZEDMAIL_KEY}"
MAIL_PASSWORD="${ZEDMAIL_KEY}"
MAIL_FROM_ADDRESS=receipts@boutique.ca
MAIL_FROM_NAME="Boutique"

# Then, as you already write it:
#   Mail::to($order->email)->send(new ReceiptMail($order));
import os, requests

res = requests.post(
    "https://zedmail.com/v1/email/send",
    headers={"Authorization": f"Bearer {os.environ['ZEDMAIL_KEY']}"},
    json={
        "from":    "receipts@boutique.ca",
        "to":      "client@example.ca",
        "subject": "Votre reçu",
        "html":    "<p>Merci de votre achat.</p>",
        "tags":    ["order-4812"],
    },
    timeout=15,
)
res.raise_for_status()
print(res.json()["message_id"])   # msg_a1b2c3d4e5f6a7b8
body, _ := json.Marshal(map[string]any{
    "from":    "receipts@boutique.ca",
    "to":      "client@example.ca",
    "subject": "Votre reçu",
    "html":    "<p>Merci de votre achat.</p>",
    "tags":    []string{"order-4812"},
})

req, _ := http.NewRequest("POST",
    "https://zedmail.com/v1/email/send", bytes.NewReader(body))
req.Header.Set("Authorization", "Bearer "+os.Getenv("ZEDMAIL_KEY"))
req.Header.Set("Content-Type", "application/json")

res, err := http.DefaultClient.Do(req)
if err != nil {
    return err
}
defer res.Body.Close()
curl https://zedmail.com/v1/email/send \
  -H "Authorization: Bearer $ZEDMAIL_KEY" \
  -H "Content-Type: application/json" \
  -d '{
        "from":    "receipts@boutique.ca",
        "to":      "client@example.ca",
        "subject": "Votre reçu",
        "html":    "<p>Merci de votre achat.</p>",
        "tags":    ["order-4812"]
      }'

# {"message_id":"msg_a1b2c3d4e5f6a7b8","status":"queued"}
Host        mail.zedmail.com
Port        465   (implicit TLS)
            2587  (STARTTLS)
Username    your API key
Password    the same API key

# Never port 25 — we do not use it, so an unblock request
# to your host is wasted effort.

# Test it from a terminal before wiring anything up:
swaks --server mail.zedmail.com:465 --tls-on-connect \
      --auth-user "$ZEDMAIL_KEY" --auth-password "$ZEDMAIL_KEY" \
      --from receipts@boutique.ca --to client@example.ca
<?php
/**
 * wp-content/mu-plugins/zedmail.php
 * A must-use plugin: no plugin to install, nothing to configure in wp-admin,
 * and it cannot be deactivated by accident.
 */
add_action('phpmailer_init', function ($mail) {
    $mail->isSMTP();
    $mail->Host       = 'mail.zedmail.com';
    $mail->Port       = 465;
    $mail->SMTPSecure = 'ssl';
    $mail->SMTPAuth   = true;
    $mail->Username   = ZEDMAIL_KEY;   // define() these in wp-config.php
    $mail->Password   = ZEDMAIL_KEY;
    $mail->setFrom('no-reply@votresite.ca', get_bloginfo('name'));
});

No SDK to install and none to wait for: it is an HTTP call and an SMTP relay. A send returns queued; the message then moves to sent and finishes as delivered, bounced, blocked or complained — by webhook, or whenever you ask. Full reference in the docs.

Two kinds of mail

A receipt and a newsletter are not the same thing

Every API key is one or the other, and the choice changes real behaviour rather than labelling it. Pick one to see exactly what it does.

Unsubscribe footer
None. Nobody should be able to opt out of their own password reset, so the footer is not added — and cannot be switched on by mistake.
List-Unsubscribe headers
Off by default, on when you scope them. A mailbox provider’s unsubscribe button on an invoice used to suppress the account’s whole transactional stream — no confirmation, nothing on screen saying so. Opt in per key and the headers come back, scoped to that key alone. Every message carries List-Help instead, so a recipient always has somewhere to go.
If someone opts out
The opt-out can be scoped to this key alone, so declining one kind of message does not silence the rest of your account.
Encryption
Verified TLS is the sensible setting here: a message to a server that cannot prove encryption is held rather than sent in the clear.
Retention
Set per stream, down to seven days, independently of your broadcast mail.
Reputation
Kept apart from your campaigns, on its own sending address. A newsletter having a bad week does not follow your receipts into the spam folder.
Unsubscribe footer
Always added, in your recipient’s language. CASL requires an opt-out mechanism and this is the one that is always there — though if your own message already carries one, we stand aside rather than add a second.
List-Unsubscribe headers
Always sent, and they matter more here: Gmail and Yahoo require one-click unsubscribe of bulk senders, and this is the stream that is bulk.
If someone opts out
Suppressed for the account and enforced at send time, so a later attempt to that address is refused rather than delivered and regretted.
Encryption
Encrypted whenever the receiving server offers it. You can require verified TLS per key if you would rather a message be held than sent unprotected.
Retention
Set per stream, down to seven days, independently of your transactional mail.
Reputation
Kept apart from your transactional mail, on its own sending address — which is the whole point: a campaign that runs into trouble does not take your password resets with it.

Simple, honest pricing

Post-paid monthly. No contracts, no minimums. Available in CAD, GBP, EUR, or USD — choose at registration.

Free tier
$0
200 emails/day — no card required
  • REST API + SMTP relay
  • Dashboard + delivery analytics
  • DKIM signing
  • Suppression list
  • Webhooks

Also available in GBP (£0.08/1k), EUR (€0.09/1k), and USD ($0.10/1k) — choose your currency at registration.

How we compare

Provider Price / 1k Data residency US-owned
Zedmail $0.15 CAD Canada ✗ No
Mailgun (Sinch) $0.80 USD USA ✓ Yes
SendGrid (Twilio) $0.89 USD USA ✓ Yes
Postmark $1.25 USD USA ✓ Yes
Amazon SES $0.10 USD USA ✓ Yes

Built for Canada, the UK, and the EU

Mailgun, SendGrid, Postmark, and AWS are all US-controlled companies. Zedmail is Canadian-owned, with no US parent, running on Canadian infrastructure — so "who owns your email provider, and under whose laws does it operate?" has a short answer you can check for yourself. That's the cherry on top.

🍁 Canadian developers

PIPEDA and Québec Law 25 require you to know where personal data is processed and who can compel access to it. Canadian infrastructure with no US parent gives you a clean, auditable answer.

🇬🇧 UK developers

UK GDPR applies to transfers outside the UK. Canada holds an adequacy decision — so your email provider sits in a recognized adequate country, and is Canadian-owned with no US parent.

🇪🇺 EU developers

GDPR Chapter V restricts transfers to third countries. Canada has an EU adequacy decision. Data Processing Agreement available on request. Canadian-owned, with no US parent.

📋 Compliance built in

Hard bounces and spam complaints auto-suppress. Unsubscribe headers injected on every send. DKIM signed. CASL + GDPR ready out of the box — not something you configure manually.

🇺🇸 US developers — you're welcome here too

Zedmail is open to US customers. Your emails will be sent from Canadian infrastructure. Pricing is available in USD ($0.10/1k). The only thing you're leaving behind is a US-owned provider.

🌍 Every other developer, too

Wherever you are, you're welcome here. Any developer in the world can sign up and send through Zedmail — and choose to be billed in Canadian dollars (CAD), British pounds (£), euros (€), or US dollars ($). Pick your currency at registration.