Docs pages

Recipe: Microsoft 365 on a subdomain#

Set up Microsoft 365 mail on a host such as advisor.example.com. The flow is the same as Google Workspace: add the verification record, wait until it is live, verify, then add the mail records. Everything goes on the host, never on the root domain. The examples are Dynadot style; any of the six API styles works the same way.

The records#

Microsoft shows the exact values for your tenant in the Microsoft 365 admin center under Settings > Domains (and DKIM in the Microsoft Defender portal, under email authentication settings). Copy them from there; the values below only show their shape.

Step Record (host form) Value
1. Verify the domain TXT @ MS=ms12345678
2. Mail MX @, priority 0 The value Microsoft shows, ending in mail.protection.outlook.com (for example advisor-example-com.mail.protection.outlook.com)
3. SPF TXT @ v=spf1 include:spf.protection.outlook.com -all
4. Outlook setup CNAME autodiscover autodiscover.outlook.com
5. DKIM CNAME selector1._domainkey and CNAME selector2._domainkey The two targets Microsoft shows
6. DMARC TXT _dmarc v=DMARC1; p=quarantine

1. Verify#

Shell
curl https://api.maildns.io/api3.json \
  --data-urlencode key=KEY \
  --data-urlencode command=set_dns2 \
  --data-urlencode domain=advisor.example.com \
  --data-urlencode add_dns_to_current_setting=1 \
  --data-urlencode main_record_type0=txt \
  --data-urlencode main_record0=MS=ms12345678

Poll dns_status with subdomain=@, record_type=txt, value=MS=ms12345678 until Live is yes, then press Verify in the admin center.

2 to 4, and 6. Mail records#

Shell
curl https://api.maildns.io/api3.json \
  --data-urlencode key=KEY \
  --data-urlencode command=set_dns2 \
  --data-urlencode domain=advisor.example.com \
  --data-urlencode add_dns_to_current_setting=1 \
  --data-urlencode main_record_type0=mx \
  --data-urlencode main_record0=advisor-example-com.mail.protection.outlook.com \
  --data-urlencode main_recordx0=0 \
  --data-urlencode main_record_type1=txt \
  --data-urlencode 'main_record1=v=spf1 include:spf.protection.outlook.com -all' \
  --data-urlencode subdomain0=autodiscover \
  --data-urlencode sub_record_type0=cname \
  --data-urlencode sub_record0=autodiscover.outlook.com \
  --data-urlencode subdomain1=_dmarc \
  --data-urlencode sub_record_type1=txt \
  --data-urlencode 'sub_record1=v=DMARC1; p=quarantine'

5. DKIM#

Add the two CNAMEs with the targets Microsoft shows (selector1-... and selector2-...), wait until both are live, then turn DKIM signing on in the Defender portal:

Shell
curl https://api.maildns.io/api3.json \
  --data-urlencode key=KEY \
  --data-urlencode command=set_dns2 \
  --data-urlencode domain=advisor.example.com \
  --data-urlencode add_dns_to_current_setting=1 \
  --data-urlencode subdomain0=selector1._domainkey \
  --data-urlencode sub_record_type0=cname \
  --data-urlencode sub_record0=SELECTOR1_TARGET \
  --data-urlencode subdomain1=selector2._domainkey \
  --data-urlencode sub_record_type1=cname \
  --data-urlencode sub_record1=SELECTOR2_TARGET

Replace SELECTOR1_TARGET and SELECTOR2_TARGET with the two values from the Defender portal.

Things to watch#

  • One SPF record and one DMARC record per name. If the host already has one, merge instead of adding a second.
  • A CNAME can't share its name with other records, so autodiscover and the two _domainkey names must have nothing else on them.
  • The Python script in the Google recipe adapts easily: change the values in verify and mail, and make dkim add the two CNAMEs.