Get your API key
Getting started

Domains & DNS

A domain is what lets MailKite receive mail for you and send authenticated mail on your behalf. You can add unlimited domains — one per product, per environment, per tenant — at no per-domain cost.

Add a domain

Add any domain or subdomain you control. Subdomains like mail.myapp.ai or a free myapp.mailkite.dev are a great fit and keep your root domain's reputation separate.

add a domain
const res = await mk.createDomain({ domain: "myapp.ai" });
Install Docs →

The response includes the DNS records to publish. New domains start in pending and move to verified once DNS resolves.

Register a new domain

Don't have a domain yet? Register one from the dashboard and we'll set it up for you — you're the legal owner. Search a name (we check popular TLDs like .com, .ai, .io, .dev), pick an available one, and we register it in your name and provision the mail DNS automatically, so it's usually verified the moment it's registered — no DNS to paste.

Registration requires a card on file (add it in Billing). The price shown is what you pay — the registrar's cost plus payment processing and a small service fee. Domain registrations are non-refundable. Your card is also used for usage-based billing (below).

Free MailKite subdomain

The fastest start: claim a free MailKite subdomain — a your-app.<base> host on a zone we run. We set up the DNS for you, so it works the instant you claim it — no registrar, no card, no DNS. Great for trying MailKite or for projects that don't need a custom domain.

Claim one from the dashboard, with mailkite domains claim your-app, or over the API — see automated onboarding. Which zone new subdomains are handed out under changes over time, and more than one may be offered, so read the current base from the API rather than hard-coding a hostname. Subdomains claimed on a retired zone keep working.

The DNS records

Add these four records at your DNS provider. Names are shown for myapp.ai — substitute your own domain.

TypeNameValuePurpose
MX myapp.ai mx.mailkite.dev (priority 10) Routes inbound mail to MailKite. Required to receive.
TXT myapp.ai v=spf1 include:mailkite.dev ~all SPF — authorizes MailKite to send for the domain.
TXT mailkite._domainkey.myapp.ai v=DKIM1; k=rsa; p=… DKIM — signs outbound so it passes authentication.
TXT _dmarc.myapp.ai v=DMARC1; p=none; DMARC — alignment policy. Start at none, tighten later.
The exact values — including your per-domain DKIM public key — are shown in the dashboard and returned from POST /api/domains and GET /api/domains/:id. Always copy from there rather than this page.

Not sure where these go at your DNS host? Follow the step-by-step DNS setup guides for GoDaddy, Cloudflare, Namecheap, Squarespace Domains, and Amazon Route 53.

Verify

After publishing the records, trigger a check. MailKite looks up your records over DNS-over-HTTPS and records the result.

verify a domain
await mk.verifyDomain("dom_…");
Install Docs →
response
{
"status": "verified",
"checks": { "mx": true, "spf": true, "dkim": true, "dmarc": true },
"checkedAt": 1750000000000
}

A domain becomes verified as soon as MX resolves to mx.mailkite.dev — that's the record that enables receiving. SPF, DKIM, and DMARC are reported separately and monitored on an ongoing basis so you know if a record drifts. DNS can take anywhere from a minute to a few hours to propagate; re-run verification until everything is green.

Addresses on a domain

Once verified, every address on the domain receives. By default a catch-all routes all mail (*@myapp.ai) to the webhook you set for the domain. To split traffic — say, send support@ to one endpoint and billing@ to another — create per-address routes. This is what lets you give every agent, task, or tenant its own address with no extra setup.

Removing a domain

remove a domain
await mk.deleteDomain("dom_…");
Install Docs →

Deleting a domain stops inbound routing for it. Remove the MX record at your DNS provider too if you no longer want mail attempted for the domain.

Next: receive your first message, or set up authentication for the API.