Email DNS
Generating MX/SPF/DKIM/DMARC records for Google Workspace, Microsoft 365, and Zoho.
Connecting a domain points web traffic at your product. Many customers also
want email on that domain — Google Workspace, Microsoft 365, or Zoho. The
control-plane generates the exact MX / SPF / DKIM / DMARC records for a chosen
provider, and merges SPF into any record the domain already publishes so you
never end up with two v=spf1 records (which silently breaks SPF).
Generate records
curl -X POST http://localhost:8080/v1/email/records \
-H "Authorization: Bearer <YOUR_KEY_OR_WIDGET_TOKEN>" \
-H "Content-Type: application/json" \
-d '{"domain":"acme.com","provider":"google_workspace"}'{
"provider": "google_workspace",
"domain": "acme.com",
"records": [
{ "host": "acme.com", "type": "MX", "value": "smtp.google.com", "ttl": 3600, "priority": 1 },
{ "host": "acme.com", "type": "TXT", "value": "v=spf1 include:_spf.google.com ~all", "ttl": 3600 },
{ "host": "_dmarc.acme.com", "type": "TXT", "value": "v=DMARC1; p=none;", "ttl": 3600 }
],
"notes": [
"DKIM: generate a key in Google Admin console … then add a TXT record at google._domainkey.acme.com (pass dkim_value to include it here).",
"DMARC starts at p=none (monitor only). Once you've confirmed legitimate mail passes, tighten to quarantine, then reject."
]
}The endpoint is a pure generator — it never writes DNS. Add the records
manually, or use POST /v1/connections/{id}/email:apply with the same
options to have a delegated credential write the safe records for you (the apex
SPF is returned as manual_records, never auto-written). The widget's optional
email step (email: true) drives email:apply behind a preview/confirm screen.
email:applywrites for the connection's own domain (or its apex). It does not accept an arbitrary domain, andrecords:applyonly re-applies the connection's web records — it does not write email records.
Supported providers
provider | Records emitted |
|---|---|
google_workspace | MX smtp.google.com, SPF _spf.google.com, DMARC, DKIM (with key) |
microsoft365 | MX <domain>.mail.protection.outlook.com, autodiscover CNAME, SPF spf.protection.outlook.com, DKIM selector1/2 CNAMEs (with m365_tenant), DMARC |
zoho | MX mx/mx2/mx3.zoho.com, SPF zoho.com, DMARC, DKIM (with key) |
Request fields
| Field | Notes |
|---|---|
domain (required) | The email domain, e.g. acme.com. |
provider (required) | One of the slugs above. |
dkim_value | The DKIM public key. If omitted, DKIM is described in a note instead of emitted (the key is issued by your provider). |
dkim_selector | Overrides the default selector (google / zoho). |
m365_tenant | Your <tenant>.onmicrosoft.com label — required to emit the Microsoft 365 DKIM CNAMEs. |
dmarc_policy | none (default), quarantine, or reject. |
dmarc_rua | Aggregate-report mailbox, e.g. dmarc@acme.com. |
existing_spf | An SPF record the domain already publishes; the provider's SPF is merged into it. |
SPF merge
A domain must have exactly one v=spf1 record. If the customer already
sends mail (say via Mailgun), pass their current record as existing_spf and the
provider's mechanisms are folded in, deduped, with a single terminal all (the
existing record's qualifier wins, so a merge never loosens the policy):
existing_spf: v=spf1 include:mailgun.org ~all
provider: v=spf1 include:_spf.google.com ~all
→ merged: v=spf1 include:mailgun.org include:_spf.google.com ~allDKIM & DMARC
- DKIM keys are generated in the provider's admin console (they're unique per
domain), so we can't derive them. Pass
dkim_valueto include the record, or follow the returned note to add it yourself. - DMARC starts at
p=none(monitor only). After confirming legitimate mail passes DKIM/SPF, tighten toquarantine, thenreject.