Skip to content

Bring your own keys (BYOK)

Mailway is not an email provider — it sits between your app and yours. You add your provider accounts with your own API keys; Mailway routes each send through them and fails over when one refuses a send. You keep the provider relationship, the sending reputation, and the provider’s pricing.

Provider Transports Delivery events
Amazon SES API (raw-capable), SMTP ✔ full setup guide
SendGrid API, SMTP ✔ full setup guide
Mailgun API (raw-capable), SMTP ✔ full setup guide
Postmark API, SMTP ✔ full setup guide
Mailtrap API, SMTP ✔ full setup guide
Mandrill API, SMTP ✔ full setup guide
Brevo API, SMTP ✔ full setup guide
Resend API, SMTP ✔ full setup guide
Mailjet API, SMTP ✔ full setup guide
MailerSend API, SMTP ✔ full setup guide
Nuntly API, SMTP ✔ full setup guide
SMTP2GO API, SMTP ✔ full setup guide
Gmail / Google Workspace SMTP —
Microsoft 365 SMTP, set up as Any SMTP server — setup guide
SparkPost SMTP, set up as Any SMTP server — setup guide
Elastic Email SMTP, set up as Any SMTP server — setup guide
Zoho ZeptoMail SMTP, set up as Any SMTP server — setup guide
Any SMTP server SMTP —

Transports: you add each provider account once — one set of credentials — and Mailway picks the transport per message: mail your apps relay through Mailway’s SMTP endpoint goes out over the provider’s SMTP endpoint (byte-for-byte), mail from the HTTP API or the console goes out over the provider’s API. Where one key serves both (SendGrid, Postmark, Mailtrap, Mandrill, Nuntly, and an Amazon SES IAM key), both transports come with it. An account’s Send via setting can restrict it to one transport; see SMTP mail through API providers for what that means for relayed mail. Delivery events (confirmed delivery, bounces, complaints flowing back into Mailway) are live for Amazon SES, SendGrid, Mailgun, Postmark, Mailtrap, Mandrill, Brevo, Resend, Mailjet, MailerSend, Nuntly, and SMTP2GO; Gmail / Google Workspace and any SMTP server (including Microsoft 365, SparkPost, Elastic Email, and Zoho ZeptoMail) report accept or reject at handoff only.

Every provider alters its own copy of a message before delivery, some lightly, some heavily. We tested what each one changes, including what happens to a DKIM signature your app applies: What providers change.

  1. In the console, open Providers → New provider and add the provider account with its credentials. Providers belong to the team; secrets are encrypted at rest and never displayed again after you save them.
  2. Open the project that should use it and attach the provider. A project can attach several.
  3. Order matters: the attach order anchors the failover chain — which provider gets the first try depends on the project’s routing strategy; when a provider refuses the send, it falls through to the next.

Each project has a strategy deciding which attached provider gets a send (changeable anytime in the project’s settings):

Strategy Picks
random (the default) any attached provider, evening out over time
fallback strictly in attach order — the first provider gets every send, the rest are backup
round-robin rotates through the chain, send by send
free-first providers with free allowance left go first, counted approximately

free-first reads the Free tier quota you maintain on each provider (for example Mailtrap’s 4,000/month) and spends it before anything that costs money. A provider whose free tier is exhausted drops behind the rest but remains a failover target — deliverability outranks economy.

Whatever the strategy, a failed attempt falls through to the next attached provider, and a per-send pin overrides the strategy entirely. For mail relayed through the SMTP endpoint one more ordering applies before the strategy — see SMTP mail through API providers.

Before committing to a change, the project page’s routing simulator (Team and up) replays your recent traffic through a hypothetical configuration — a different strategy, or with a provider removed (“what if SES were down?”) — using the exact same routing engine live sends use, and shows how first attempts would have split. It projects routing, never outcomes.

  • Failover needs at least two providers attached to the project, and is included on Pro and up.
  • A send that fails on one provider retries down the chain — a mail is only exhausted when every attempt has failed.
  • Every attempt is recorded: the console shows the full per-attempt chain (provider, duration, response), and mails saved by a retry are counted as rescued on the console’s Dashboard — the number that tells you what the chain is worth.
  • A hard bounce for a single-recipient send stops retrying immediately — re-sending a permanent reject to another provider would only hurt your reputation. Only a reject aimed at the recipient counts: a provider refusing your account (an unverified sender domain, a sender it won’t accept) fails over to the next provider instead.
  • Failover is only as independent as the providers behind it. Resend sends through Amazon SES, so SES and Resend back each other up against account-level trouble but can share an outage; see What providers change.

Mail your apps hand to Mailway’s SMTP relay is promised byte-for-byte. An account that can send over SMTP relays it over SMTP — the original bytes, nothing to decide. (What the provider then does to its own copy is up to the provider; What providers change lists it for each one. Mailway still hands over the exact bytes and keeps them in the archive.) The question only arises for an account that can’t: one set to Send via: API only, or one whose credentials only cover the API (a Mailgun or Brevo API key without the separate SMTP login). Then it depends on the API:

  • Raw-capable APIs — Amazon SES (SendRawEmail) and Mailgun (the MIME endpoint) accept a complete raw message over their API — relay the original bytes byte-for-byte, by default. The fidelity promise holds; no configuration needed.
  • Structured-only APIs (every other provider’s API: SendGrid, Postmark, Brevo, Mandrill, Mailtrap, Resend, Mailjet, MailerSend, Nuntly, and SMTP2GO) accept only JSON fields — carrying the original bytes is impossible. Relayed mail skips such an account by default; the project’s routing view says so on the affected hop.

For those accounts there is an opt-in. A project admin can enable re-encoding on that provider’s attachment (per project, per provider; the change is audited). Mailway then rebuilds the message from the archived original — headers, HTML and text bodies, and attachments including inline images — and sends it as a structured API call. The consequences, stated plainly:

  • The delivered message may not be 100% identical to what your app handed over. It is a faithful reconstruction, not the original bytes.
  • A DKIM signature your app applied before handing off will not survive the rebuild — the provider signs with its own DKIM instead, as it does for any structured API send.
  • The console marks every such attempt re-encoded — on the mail, in the list, and on its per-attempt timeline — so a fidelity caveat is never invisible.
  • No proof-of-delivery certificate is issued for a re-encoded delivery: Mailway won’t certify byte equality it didn’t preserve.

Every mail carries a fidelity value: relayed (Mailway handed the provider the exact bytes your app sent), constructed (the mail was built from HTTP API or console fields, so there were no original bytes), or re-encoded (rebuilt for a structured-only API, as above). To audit fidelity across your mail, filter the console with fidelity:re-encoded (or relayed / constructed); troubleshooting covers what to check when a delivery isn’t byte-for-byte.

Mail submitted through Mailway’s own HTTP API or console never faces any of this. It arrives as structured fields, so every provider can carry it without re-encoding. The provider may still add to it: Brevo, for one, delivers text as HTML with a tracking pixel.

One default worth knowing: independent of the routing strategy, SMTP mail tries the accounts that relay over SMTP first, then accounts that relay over a raw-capable API, and re-encoding accounts only after every byte-for-byte one has been attempted — fidelity outranks strategy preference. Explicit per-send pins still override.

The HTTP API can pin a message to a specific provider ("routing": { "provider": "amazon-ses" }) or an ordered preference list. A pin names the provider account; Mailway still picks its transport. A pinned provider that isn’t attached to the project fails loudly with 422 routing_provider_not_configured — never a silent reroute. Rules can also route by content: send everything matching invoice through SES, everything else wherever.