What this gets you
Mailgun asks a lot of a customer's DNS. A single sending domain needs an SPF record, DKIM, usually a tracking CNAME, and — if the customer receives mail through Mailgun — two MX records. That's four to six entries, published by someone who does not work for you, in a control panel you cannot see.
Connecting Mailgun to DNSconfig reads those requirements straight from your Mailgun account, so they are always exactly what Mailgun asks for today, and turns "did the customer set it up correctly?" into something on a dashboard.
Get the API key
In Mailgun, open your account's API keys and copy the private (primary)
key. DNSconfig sends it as HTTP basic auth with the username
api, which is how Mailgun's API expects it.
The key is read-only in practice here: the integration calls
/v4/domains and /v5/accounts/subaccounts and
nothing else. It never sends mail, changes routes, or touches
suppressions.
Check it — and find out which region you're on
Mailgun runs two entirely separate stacks, US and EU, with different API hosts and different data. An EU account queried on the US host returns 401, which looks exactly like a bad key. This one command tells you both things at once:
# US
curl -s -o /dev/null -w "US: %{http_code}\n" \
--user "api:$MG_KEY" https://api.mailgun.net/v4/domains
# EU
curl -s -o /dev/null -w "EU: %{http_code}\n" \
--user "api:$MG_KEY" https://api.eu.mailgun.net/v4/domains
| Result | Means |
|---|---|
One returns 200 | That's your region. Remember which — you'll set it in step 3. |
Both return 401 | The key is wrong or was truncated when copied. |
Getting the region wrong is the single most common problem with this integration, and it is invisible from the DNSconfig side — the connection simply finds no domains.
Add the customer's sending domain
In Mailgun: Sending → Domains → Add New Domain. Enter the domain
(or subdomain — Mailgun recommends something like
mg.customer.com) and create it.
Mailgun then shows the DNS records it needs. You'll typically get:
| Record | Purpose |
|---|---|
TXT SPF | Authorizes Mailgun to send for the domain. |
TXT DKIM | Signs outbound mail so receivers can verify it. |
CNAME tracking | Opens and clicks, branded on the customer's domain. |
MX ×2 | Only if the customer receives mail through Mailgun. |
Connect it in DNSconfig
Open Connections, add a Mailgun connection, paste the API
key, and — if step 1 said EU — set the region to eu.
It defaults to us.
Your key is encrypted before it is stored and is never returned by any read; the connection list only ever shows whether a credential is configured, never the value.
Managing connections requires a console session, or an API key carrying
the secrets scope. See the
developer documentation.
Pull the records
Press Sync now on the connection. You'll get back a count of what changed:
{ "source": "mailgun",
"added": 5, "updated": 0, "retired": 0, "unchanged": 0 }
Those records are now expected state, under a customer named after the domain — created for you if it didn't already exist. One connection covers every domain in the account; you don't add one per domain.
200.
What happens from then on
- Every hour, the connection is re-pulled. Records Mailgun adds appear as new expected state; records it stops requiring are retired. Anything you entered by hand is never touched.
- Four times an hour, every record is checked against live DNS from several independent resolvers, and counts as correct only when a majority of those that answered agree — so a record published minutes ago reads as propagating rather than failing.
-
SPF is compared by meaning, not by string. A customer who
already had an SPF record and merged Mailgun's
include:into it still passes; one who is missing the include is reported as partial, naming what's absent. - When a record's status changes, you're alerted — email, Slack, or your own webhook. Only transitions alert, so a long-broken record doesn't page you every fifteen minutes.
Connection options
The defaults suit most accounts. Set these only if you need them.
| Option | Effect |
|---|---|
region |
us (default) or eu. The one setting most likely to matter — see step 1. |
domains |
A list of domain names to pull, instead of every domain on the account. |
subaccounts |
A list of subaccount ids to iterate. Enterprise only. |
single_account |
Skip subaccount discovery entirely. Rarely needed — the puller already falls back to single-account mode when an account has no subaccounts. |
Troubleshooting
| Symptom | Cause |
|---|---|
Sync reports added: 0 |
Wrong region, or no domain added in Mailgun yet. Check the region first. |
| Sync fails, vendor unreachable | The key was rotated or mistyped. Re-run the step 1 curls. |
| MX records always failing | The customer doesn't receive mail through Mailgun. Delete those two records in DNSconfig — see step 2. |
| SPF reported partial | The domain has an SPF record but without Mailgun's include:. The hint names exactly what to add — a domain must have only one SPF record, so it has to be merged, not added alongside. |
| Records appeared under an unexpected customer | A customer already owned that domain, so the pull routed to it rather than creating a second one. Working as intended. |
Also using SendGrid? Connect SendGrid.
← Developer documentation