Skip to main content

Overview

A domain is a custom sending domain added to a Microsoft 365 tenant. Microsoft imposes no hard limit on custom domains per tenant. TenantCore recommends 12 domains per tenant as the optimal structure for cold email infrastructure. TenantCore generates all DNS records required to configure the domain at your registrar and queries live DNS status on each domain so you can monitor authentication health across your infrastructure. The standard TenantCore structure is:
1 tenant
└── 12 domains
    └── 3 mailboxes each = 36 mailboxes total
Domains must be verified in Microsoft 365 before mailboxes can be provisioned on them. Add the domain first, configure the DNS records at your registrar, then verify via the TenantCore app.

List domains

Returns all custom domains registered on a tenant, including live DNS health status.
GET /v1/tenants/{tenant_id}/domains
Path parameters
ParameterTypeDescription
tenant_idstringThe Microsoft tenant GUID
Example request
curl https://api.tenantcore.io/v1/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/domains \
  -H "Authorization: Bearer tc_live_your_key"
Example response
{
  "tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "domains": [
    {
      "id": "uuid",
      "domain_name": "mail.acmecorp.com",
      "is_default": true,
      "is_verified": true,
      "spf_status": "v=spf1 include:spf.protection.outlook.com -all",
      "dkim_status": "healthy",
      "dmarc_status": "v=DMARC1; p=quarantine; rua=mailto:dmarc@acmecorp.com",
      "mx_status": "acmecorp-com.mail.protection.outlook.com.",
      "last_checked": "2025-04-20T08:00:00Z"
    }
  ],
  "count": 1
}
Response fields
FieldTypeDescription
domain_namestringThe custom domain
is_defaultbooleanWhether this is the tenant’s primary domain
is_verifiedbooleanWhether Microsoft has verified this domain
spf_statusstringRaw SPF TXT record, or "missing"
dkim_statusstring"healthy", "partial", "missing", or selector detail
dmarc_statusstringRaw DMARC TXT record, or "missing"
mx_statusstringRaw MX record, or "missing"
last_checkedtimestampWhen DNS was last queried
Errors
StatusCodeDescription
404tenant_not_foundTenant does not exist or belongs to a different account

Add domain

Adds a custom domain to a tenant in Microsoft 365 and returns the DNS records you need to configure at your registrar. The domain is created in Microsoft but remains unverified until you add the required DNS records and trigger verification.
POST /v1/tenants/{tenant_id}/domains
Path parameters
ParameterTypeDescription
tenant_idstringThe Microsoft tenant GUID
Request body
{
  "domain": "mail.acmecorp.com"
}
FieldTypeRequiredDescription
domainstringYesThe custom domain to add. Must be a valid domain. .onmicrosoft.com domains are not allowed.
Example request
curl -X POST \
  https://api.tenantcore.io/v1/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/domains \
  -H "Authorization: Bearer tc_live_your_key" \
  -H "Content-Type: application/json" \
  -d '{"domain": "mail.acmecorp.com"}'
Example response
{
  "status": "success",
  "tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "domain": {
    "domain_name": "mail.acmecorp.com",
    "is_default": false,
    "is_verified": false
  },
  "verification_dns_records": [
    {
      "recordType": "domainDnsTxtRecord",
      "label": "@",
      "text": "MS=ms12345678",
      "ttl": 3600
    }
  ],
  "service_configuration_records": [
    {
      "recordType": "domainDnsMxRecord",
      "label": "@",
      "mailExchange": "mail.acmecorp.com.mail.protection.outlook.com",
      "preference": 0,
      "ttl": 3600
    }
  ],
  "live_dns_status": {
    "spf_status": "missing",
    "dkim_status": "missing",
    "dmarc_status": "missing",
    "mx_status": "missing"
  },
  "dkim_verification_state": {
    "status": "missing",
    "message": "missing (selector1, selector2)"
  }
}
After adding a domain
  1. Add the verification_dns_records TXT record at your registrar
  2. Add all service_configuration_records (MX, CNAME for DKIM, TXT for SPF)
  3. Wait for DNS propagation (typically 5 to 30 minutes, up to 48 hours)
  4. Trigger domain verification from the TenantCore app
Errors
StatusCodeDescription
400domain_limit_reachedTenant already has 12 domains
400Invalid domain format or .onmicrosoft.com domain
404tenant_not_foundTenant does not exist or belongs to a different account

Verify domain

Triggers Microsoft domain verification after DNS records have been configured. This is required before mailboxes can be created and sending can begin.

POST /v1/tenants/{tenant_id}/domains/{domain_name}/verify

Path parameters
ParameterTypeDescription
tenant_idstringThe Microsoft tenant GUID
domain_namestringThe custom domain name
Example request
curl -X POST \
  https://api.tenantcore.io/v1/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/domains/mail.acmecorp.com/verify \
  -H "Authorization: Bearer tc_live_your_key"
Example response
{
  "status": "success",
  "domain_name": "mail.acmecorp.com",
  "is_verified": true,
  "message": "Domain successfully verified in Microsoft 365"
}
Errors
StatusCodeDescription
400verification_failedDNS records not yet propagated or incorrect
404domain_not_foundDomain is not registered on this tenant

Enable DKIM

Enables DKIM signing for a verified domain. This is required for full email authentication and deliverability.
POST /v1/tenants/{tenant_id}/domains/{domain_name}/enable-dkim
Path parameters
ParameterTypeDescription
tenant_idstringThe Microsoft tenant GUID
domain_namestringThe custom domain name
Example request
curl -X POST \
  https://api.tenantcore.io/v1/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/domains/mail.acmecorp.com/enable-dkim \
  -H "Authorization: Bearer tc_live_your_key"
Example response
{
  "status": "success",
  "domain_name": "mail.acmecorp.com",
  "dkim_status": "enabled",
  "message": "DKIM successfully enabled"
}
Errors
StatusCodeDescription
400dkim_not_readyRequired CNAME records not found in DNS
404domain_not_foundDomain is not registered on this tenant

Get DKIM status

Returns the current DKIM state for a domain. Useful for polling until DNS propagation is complete and DKIM can be enabled.
GET /v1/tenants/{tenant_id}/domains/{domain_name}/dkim-status
Path parameters
ParameterTypeDescription
tenant_idstringThe Microsoft tenant GUID
domain_namestringThe custom domain name
Example request
curl https://api.tenantcore.io/v1/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/domains/mail.acmecorp.com/dkim-status \
  -H "Authorization: Bearer tc_live_your_key"
Example response
{
  "domain_name": "mail.acmecorp.com",
  "dkim_status": "pending",
  "selectors": {
    "selector1": "missing",
    "selector2": "propagated"
  },
  "ready_to_enable": false,
  "last_checked": "2025-04-20T08:00:00Z"
}
Response fields
FieldTypeDescription
dkim_statusstring"pending", "ready", "enabled"
selectorsobjectStatus of selector1 and selector2
ready_to_enablebooleanWhether DKIM can be enabled
last_checkedtimestampLast DNS check

Get DNS records

Returns the stored DNS records and current DNS health for a specific domain. This does not trigger a live DNS re-check — it returns what was last recorded. Use the TenantCore app to trigger a fresh DNS check.
GET /v1/tenants/{tenant_id}/domains/{domain_name}/dns
Path parameters
ParameterTypeDescription
tenant_idstringThe Microsoft tenant GUID
domain_namestringThe custom domain name, e.g. mail.acmecorp.com
Example request
curl https://api.tenantcore.io/v1/tenants/xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx/domains/mail.acmecorp.com/dns \
  -H "Authorization: Bearer tc_live_your_key"
Example response
{
  "tenant_id": "xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx",
  "domain_name": "mail.acmecorp.com",
  "is_default": false,
  "is_verified": true,
  "dns_status": {
    "spf": "v=spf1 include:spf.protection.outlook.com -all",
    "dkim": "healthy",
    "dmarc": "v=DMARC1; p=quarantine",
    "mx": "mail.acmecorp.com.mail.protection.outlook.com."
  },
  "verification_dns_records": [],
  "service_configuration_records": [
    {
      "recordType": "domainDnsMxRecord",
      "label": "@",
      "mailExchange": "mail.acmecorp.com.mail.protection.outlook.com",
      "preference": 0,
      "ttl": 3600
    },
    {
      "recordType": "domainDnsCnameRecord",
      "label": "selector1._domainkey",
      "canonicalName": "selector1-mail-acmecorp-com._domainkey.acmecorp.onmicrosoft.com",
      "ttl": 3600
    },
    {
      "recordType": "domainDnsCnameRecord",
      "label": "selector2._domainkey",
      "canonicalName": "selector2-mail-acmecorp-com._domainkey.acmecorp.onmicrosoft.com",
      "ttl": 3600
    }
  ],
  "last_checked": "2025-04-20T08:00:00Z"
}
Errors
StatusCodeDescription
404tenant_not_foundTenant does not exist or belongs to a different account
404domain_not_foundDomain is not registered on this tenant