Sign in Create account
Guides

Domain DNS setup: DKIM, SPF, DMARC and MX

The DKIM, SPF, MX and tracking records, verification and sending regions.

#How it works

To send from your own domain, Postal needs you to publish a few DNS records. They prove the domain is yours and make your emails pass the SPF, DKIM and DMARC checks of mailbox providers, which keeps them out of the spam folder.

  1. Add the domain in the dashboard or with POST /domains. We recommend a subdomain used only for email, such as mail.acmestore.com, if your main domain already sends through another service.
  2. Create the records shown at your DNS provider (Cloudflare, Route 53, GoDaddy, Registro.br…).
  3. Click Verify (or call POST /domains/{id}/verify). Postal checks the records on its own for up to 72 hours and notifies you through the domain.updated webhook.

#Sending records

Example for acmestore.com in the sa-east-1 region. The exact values for your domain, especially the DKIM key, are in the dashboard and in GET /domains/{id}.

TypeNameValuePurpose
TXTpostal._domainkeyp=MIIBIjANBgkqh…IDAQABDKIM: signs each email with your domain's key.
MXpostalfeedback-smtp.sa-east-1.amazonses.com (priority 10)Return-Path: receives bounces and complaints.
TXTpostalv=spf1 include:_spf.postal.so ~allReturn-Path SPF: authorizes Postal to send.

The names are relative to the domain: postal means postal.acmestore.com. Some providers ask for the full name, others append the domain automatically; if the dashboard reports postal.acmestore.com.acmestore.com, remove the domain from the name. The postal subdomain can be a different one, set with custom_return_path when you create the domain. Because the SPF record lives on the Return-Path subdomain, your main domain's SPF does not change.

#DMARC

Postal does not require it, but the big mailbox providers (Gmail, Outlook, Yahoo) expect DMARC from anyone sending volume. If your domain does not have it yet, start by monitoring:

TypeNameValue
TXT_dmarcv=DMARC1; p=none; rua=mailto:[email protected]

Once the reports show everything passing, tighten the policy to p=quarantine and then p=reject. The deliverability diagnostic of each email warns you when DMARC is missing.

#Open and click tracking

Turn on open_tracking and click_tracking on the domain to receive the email.opened and email.clicked events. By default, tracked links use a domain from the sending infrastructure. To use an address of your own, set tracking_subdomain (for example, links) and create the record:

TypeNameValue
CNAMElinksr.sa-east-1.awstrack.me

Open tracking relies on images and is not exact: many email clients load or block images automatically.

#Receiving (MX)

To receive email on your domain (paid plans), enable capabilities.receiving and point the domain's MX to Postal:

TypeNameValue
MX@mx.postal.so (priority 10)

Heads up

Changing the MX of your main domain makes all of its email arrive at Postal instead of your current mailbox (Google Workspace, Microsoft 365…). If in doubt, use a subdomain, such as support.acmestore.com, or a free address on in.postal.so. To find out whether the domain already has MX records from another provider, call GET /domains/{id}/receiving-check: it only informs, it does not stop you from turning receiving on, and the dashboard uses the answer to warn you.

Then create inboxes for the addresses you want to receive.

#Verification status

StatusMeaning
not_startedVerification has not started yet.
pendingChecking the records.
partially_verifiedSome records are correct already; others are still missing.
verifiedAll good: the domain can send.
partially_failed72 hours have passed and some records were not found.
failed72 hours have passed without finding the records.

Each record also has its own status and, when something is wrong, a diagnostic that explains the problem (different value, duplicate record…). Fix it and verify again.

#When a record goes missing

Once verified, the domain keeps being checked every day, at a time that varies from one domain to another. If a required sending record (DKIM or the Return-Path ones) can no longer be found:

  1. Postal notes the miss and checks again in 5 minutes, so it does not react to a momentary DNS failure. A lookup that fails never counts as a missing record.
  2. If the second check agrees, the domain stays verified and keeps sending, but now carries records_missing in GET /domains/{id} (with since, deadline_at and the records that are missing). The domain.updated webhook goes out, and the team members with domain notifications on receive an email with the exact record and the deadline. Checks become hourly.
  3. If the record is still missing 72 hours after the first miss, the domain becomes failed (or partially_failed, if one of the required records is still there) and stops sending. Postal keeps looking for the records every 6 hours.
  4. When the record comes back, inside or outside the deadline, the warning goes away and the domain returns to verified on its own. Clicking Verify on a domain that is still sending only brings the check forward; on one that dropped, it restarts the 72-hour verification.

Tracking and receiving records are not part of this rule.

#Regions

The region sets where your emails are sent from and where the sending data is kept. The default is São Paulo.

RegionLocation
sa-east-1São Paulo (default)
us-east-1N. Virginia, USA
us-east-2Ohio, USA
eu-west-1Ireland
ap-northeast-1Tokyo

#TLS

With tls: "opportunistic" (the default), Postal uses TLS whenever the recipient's server accepts it and delivers without TLS when it does not. With enforced, the message is delivered only over TLS.

#Domain on another account

If Postal tells you the domain is already registered when you add it, it belongs to another account (a former employee's or an old test, for example). Prove that you control the DNS with a claim: create the TXT record postal-domain-verification=… and the domain is transferred to your account, with new DKIM keys.