A Domain Is Not an Account
On most email providers you connect an account and pick a sender. On Mailgun the domain is the unit — it is in the request path, it carries the reputation, and it lives in a region you chose once and cannot move.
Email deliverability is a reputation system, and reputation attaches to a domain rather than to an account. Most providers hide that: you sign up, verify a sender, and the domain machinery happens underneath. Mailgun puts it in front of you, and the first sign is that the domain appears in the address of every request you make. That is a design choice with consequences worth understanding before you set one up.
The domain is the thing you send from
A request to send mail here names the domain in its path. Not as a parameter, not as a header — as part of the address of the resource you are posting to.
The implication is that one account can hold several domains and they are genuinely separate sending identities. Different reputations, different statistics, different suppression lists. Sending from one tells you nothing about the other.
That is exactly right for how organisations actually work. A company sending invoices from its main domain and marketing from a subdomain is not being fussy — it is protecting the first from the second, because a marketing campaign that generates complaints should not cost you the ability to deliver an invoice.
Separating a subdomain for operational mail is the cheapest deliverability insurance there is, and it is a decision you make once, before anything is sending.
Two regions, and they do not talk
The provider operates two independent regions, and a domain belongs to one of them. The connector selects the matching interface address from your configured region.
This is worth stating plainly because it produces a confusing failure. A domain created in one region is simply not present in the other — so the wrong region produces a response saying the domain does not exist, which reads as a verification problem rather than as a routing one. People go and re-verify a domain that was fine.
| If your region setting is | And your domain lives in | You get |
|---|---|---|
| Correct | The same region | |
| Wrong | The other region | A message saying the domain does not exist |
| Not set, defaulting | The other region | The same, and no obvious clue |
It is also a genuine data residency control rather than a marketing one. Mail processed in one region stays in that region, which for organisations with European obligations is the reason to be on this provider at all.
The catch is that the choice is made when the domain is created and is not something you change afterwards. A region is a property of a domain, not a setting on an account — which is why it is worth being deliberate about on day one rather than discovering it during a compliance review.
A different wire format, and one odd credential
Two implementation details that catch people out, both of which are the provider being older than the conventions everybody now assumes.
The request is a multipart form rather than JSON. That is unusual now and it is deliberate on the provider's part — multipart is what carries file attachments naturally, and this is an interface designed around sending mail with things attached to it.
And the authentication is basic auth where the username is the fixed literal word for an interface key, with your secret as the password. It looks wrong the first time you see it. It is what the provider specifies, and putting your key in the username field instead — which is the natural guess — produces an authentication failure that tells you nothing about which half was wrong.
Both of these are the same lesson this series keeps arriving at from different directions: the conventions you have absorbed are not a specification. Every provider has three or four places where it predates or ignores them, and each one fails in a way that points somewhere else.
Translating into a form
Because every email in this system is built in one internal shape and translated outward, this connector has the most interesting translation of the set.
The internal format is structured and nested: a list of messages, each with a list of recipients as objects. A multipart form is flat — a set of named fields, with repetition rather than nesting.
So recipient lists are flattened into repeated fields, and the nested structure is unwound rather than renamed. It is more work than the other translations, and it is the price of the internal format being a real one rather than something invented to be equidistant from every provider.
Several messages, one at a time
The internal body can carry several messages. The provider takes one per request, so the connector loops.
The loop has the shape that recurs everywhere in this series and is worth naming once more. Each failure is caught inside the loop rather than around it, so one bad message costs itself and the rest still go. Anything in the list that is not shaped like a message is skipped rather than failing the batch. And the overall verdict requires at least one actual send plus no failures, so a body with nothing sendable in it is reported rather than passing as fine.
None of that is clever. It is the same four decisions, made the same way, in the sixth place they came up — which is what consistency in a codebase actually looks like.
What is in place, layer by layer
The Mailgun connector as it stands
The domain as the sending unit
Mail is sent against a specific domain rather than an account, so several domains on one account keep separate reputations and statistics.
Region-aware addressing
The interface host follows your configured region, because a domain in one region is not present in the other and the mismatch reads as a missing domain.
The provider's own authentication shape
Basic authentication with the fixed username the provider specifies and your secret as the password, rather than the arrangement everybody guesses first.
Multipart requests, as the API expects
The interface takes form data rather than JSON, which is what makes attachments natural on this provider.
Structure flattened for the wire
Nested recipient lists become repeated form fields, so the internal format stays structured while the request is what the provider wants.
One request per message, guarded individually
A failure costs its own message and the loop continues, rather than abandoning everything queued behind it.
A malformed entry skipped, not fatal
Anything in the list that is not shaped like a message is stepped over rather than failing the batch around it.
A verdict with a floor
Success requires at least one message actually sent and no failures, so a body with nothing sendable is reported rather than passing quietly.
Your own domain and credentials
Your domain, your key, your region, your reputation and your billing, stored encrypted against one workspace.
A domain's region is fixed when the domain is created. It is a data residency property rather than a setting, and it is worth choosing deliberately before anything is sending.
Three positions held on purpose
- The region is configured rather than assumed. Defaulting silently to one of two independent regions produces a failure that says the domain does not exist, which sends people to re-verify a domain that was never the problem.
- The provider's own authentication and wire format are followed rather than the conventional ones. Every provider in this series has three or four places where it predates the conventions, and each of them fails by pointing somewhere else.
- The same four loop decisions are made the same way here as everywhere else. Guard inside, skip malformed entries, require an actual send, keep every reason — consistency across connectors is worth more than a cleverer version in one of them.
Five questions about domain-based email sending
Can we use a subdomain for operational mail?
A good answer sounds like
Yes, and you should.
What ours actually is
The domain is the sending unit, so a subdomain keeps its own reputation, separate from anything else you send.
Where is our mail processed?
A good answer sounds like
The region you chose.
What ours actually is
Two independent regions; the connector addresses the one your domain lives in.
Can we move region later?
A good answer sounds like
No — say so.
What ours actually is
A region belongs to a domain and is fixed when the domain is created.
Why is our API key being rejected?
A good answer sounds like
Check where it goes.
What ours actually is
The provider expects a fixed username and your key as the password. The natural guess fails without saying which half was wrong.
What if one message in a batch fails?
A good answer sounds like
The rest still send.
What ours actually is
Each is guarded individually, and every reason is kept.
Our take
If you are setting up transactional email for the first time, the single most valuable decision is one you make before writing anything: send operational mail from a subdomain kept apart from everything else. It costs one DNS record more than not doing it, and it means the day somebody in marketing sends a campaign that generates complaints, your invoices still arrive. Deliverability problems are extremely hard to diagnose and slow to recover from, because reputation decays gradually and nobody sends you a notification when it starts. Separating the domains is the one intervention that is cheap now and impossible to retrofit cheaply later.
Keep your invoices away from your campaigns
A separate sending subdomain for operational mail is one DNS record and the best deliverability decision available to you.
Talk through email deliveryFrequently asked questions
Should we use our main domain or a subdomain?
A subdomain, almost always. Reputation attaches to the sending domain, so keeping operational mail on one of its own means a campaign or a compromised mailbox elsewhere cannot cost you the ability to deliver an invoice. It is one extra DNS record and it is not retrofittable cheaply.
Which region should we choose?
Wherever your obligations require your mail to be processed. The two regions are independent, and the choice is fixed when the domain is created rather than adjustable afterwards — so it is worth settling before anything is sending rather than during a compliance review.
Our domain is verified but the connector says it does not exist. Why?
Almost certainly a region mismatch. A domain created in one region is not present in the other, and the response says so in a way that reads as a verification problem. Check the region setting before re-verifying anything.
Why does this connector send form data rather than JSON?
Because that is what the provider's interface takes. It predates the convention that everything is JSON, and multipart is what carries attachments naturally — which is reasonable for an interface built around sending mail with files attached to it.
If one email in a batch fails, what happens to the others?
They still send. Each message is its own request, guarded on its own, and every failure is recorded with the provider's reason. The overall result reports a failure, with the detail of which messages did not go.