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#
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=ms12345678Poll 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#
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:
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_TARGETReplace 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
autodiscoverand the two_domainkeynames must have nothing else on them. - The Python script in the Google recipe adapts easily: change the values in
verifyandmail, and makedkimadd the two CNAMEs.