Domains
Register domains for email sending and receiving, manage the DNS records required for authentication and inbound routing, and verify your domain settings. Each added domain includes automatically generated DNS records for proper email delivery.
Add Domain
Register a domain. CM.com generates its DNS records: three CNAME records for sending and one MX record for receiving. Sending is enabled and receiving is disabled for a new domain, so add the MX record to your DNS if you want to receive email on this domain.
Request
POST https://api.cm.com/email/configuration/v1/configuration/add-domain
Content-Type: application/json
| Header Name | Type | Required | Description |
|---|---|---|---|
| Content-Type | string | Yes | Must be "application/json" |
{
"accountId": "50025f6a-d4fd-4a23-9e2e-bbee1cf67d2b",
"domain": "example.com",
"clickTracking": false,
"openTracking": false
}
Response Body
Successful Response (200)
{
"status": 200,
"message": "Success",
"success": true,
"domainConfig": {
"id": 97,
"accountId": "50025f6a-d4fd-4a23-9e2e-bbee1cf67d2b",
"domain": "example.com",
"createdOn": null,
"modifiedOn": null,
"deletedOn": null,
"dnsRecords": [],
"isValid": false,
"clickTracking": false,
"openTracking": false,
"sendingEnabled": false,
"receivingEnabled": false,
"status": 0
}
}
The create response does not populate the timestamps, sendingEnabled, receivingEnabled, status or the per-record dnsStatus. Read the stored state with Get Domains.
The record values above are illustrative. The value suffix depends on the environment, so always copy the records from the response.
Error Responses
| Status | Message | Cause |
|---|---|---|
| 400 | Domain cannot be empty | domain is blank. |
| 400 | Domain exceeds maximum length of 253 characters | domain is too long. |
| 400 | Invalid domain format | domain is not a valid host name. |
| 400 | Domain '{domain}' already exists for this account | The account already has this domain. |
| 400 | Invalid request. Please check your input. | accountId is not a valid account token. |
| 403 | Trial accounts are limited to a single domain | A trial account already has a domain. |
| 409 | Domain '{domain}' conflicts with a domain already in use by another account | Trial accounts only: another account already registered this domain. |
| 500 | Unable to create Domain | The domain could not be stored. |
Every error uses the same envelope with success: false:
{
"status": 403,
"message": "Trial accounts are limited to a single domain",
"success": false,
"domainConfig": null
}
Get Domains
Retrieve all domain configurations for a specific logical account.
Request Header
GET https://api.cm.com/email/configuration/v1/configuration/accounts/{logicalAccountId}
| Parameter | Type | Required | Description |
|---|---|---|---|
| logicalAccountId | UUID | Yes | The logical account identifier |
Response Body
Successful Response (200)
{
"status": 200,
"message": "Success",
"success": true,
"domains": [
{
"id": 97,
"accountId": "50025f6a-d4fd-4a23-9e2e-bbee1cf67d2b",
"domain": "example.com",
"createdOn": "2026-10-08T10:41:24.432089",
"modifiedOn": null,
"deletedOn": null,
"dnsRecords": [
{
"host": "cm50025f6ad4fd4a239e2ebbee1cf67d2b.example.com",
"type": "CNAME",
"value": "50025f6ad4fd4a239e2ebbee1cf67d2b.email.cm.com.",
"purpose": "sending",
"priority": null,
"dnsStatus": 2
},
{
"host": "cm150025f6ad4fd4a239e2ebbee1cf67d2b._domainkey.example.com",
"type": "CNAME",
"value": "50025f6ad4fd4a239e2ebbee1cf67d2bcm1._domainkey.email.cm.com.",
"purpose": "sending",
"priority": null,
"dnsStatus": 2
},
{
"host": "cm250025f6ad4fd4a239e2ebbee1cf67d2b._domainkey.example.com",
"type": "CNAME",
"value": "50025f6ad4fd4a239e2ebbee1cf67d2bcm2._domainkey.email.cm.com.",
"purpose": "sending",
"priority": null,
"dnsStatus": 2
},
{
"host": "example.com",
"type": "MX",
"value": "mx.email.cm.com.",
"purpose": "receiving",
"priority": 10,
"dnsStatus": 3
}
],
"isValid": false,
"clickTracking": false,
"openTracking": false,
"sendingEnabled": true,
"receivingEnabled": true,
"status": 3
}
]
}
| Field | Description |
|---|---|
sendingEnabled | Sending capability. Enabled by default for a new domain. |
receivingEnabled | Receiving capability. Disabled by default for a new domain. See Receive Email on a Domain. |
status | Overall verification state: 1 not verified yet, 2 verified, 3 verification ran and failed. |
dnsRecords[].purpose | sending (CNAME) or receiving (MX). |
dnsRecords[].priority | MX preference. null for CNAME records. |
dnsRecords[].dnsStatus | Per-record state, same values as status. |
Error Responses
| Status | Message | Cause |
|---|---|---|
| 400 | Invalid request. Please check your input. | logicalAccountId is empty. |
| 400 | Unable to get the domain config | The domains could not be read. |
| 500 | Unable to get the domain config | Unexpected failure while reading. |
{
"status": 500,
"message": "Unable to get the domain config",
"domains": [],
"success": false
}
Get DNS Records
Retrieve DNS records for a specific domain within an account.
Request Header
GET https://api.cm.com/email/configuration/v1/configuration/accounts/{logicalAccountId}/domains/{domainId}
| Parameter | Type | Required | Description |
|---|---|---|---|
| logicalAccountId | UUID | Yes | The logical account identifier |
| domainId | integer | Yes | The domain identifier |
Response Body
Successful Response (200)
{
"status": 200,
"message": "Success",
"success": true,
"dnsRecords": [
{
"id": 223,
"fromDomain": 97,
"host": "cm50025f6ad4fd4a239e2ebbee1cf67d2b.example.com",
"type": "CNAME",
"value": "50025f6ad4fd4a239e2ebbee1cf67d2b.email.cm.com.",
"isValid": true,
"purpose": "sending",
"priority": null,
"dnsStatus": 2
},
{
"id": 224,
"fromDomain": 97,
"host": "cm150025f6ad4fd4a239e2ebbee1cf67d2b._domainkey.example.com",
"type": "CNAME",
"value": "50025f6ad4fd4a239e2ebbee1cf67d2bcm1._domainkey.email.cm.com.",
"isValid": true,
"purpose": "sending",
"priority": null,
"dnsStatus": 2
},
{
"id": 225,
"fromDomain": 97,
"host": "cm250025f6ad4fd4a239e2ebbee1cf67d2b._domainkey.example.com",
"type": "CNAME",
"value": "50025f6ad4fd4a239e2ebbee1cf67d2bcm2._domainkey.email.cm.com.",
"isValid": true,
"purpose": "sending",
"priority": null,
"dnsStatus": 2
},
{
"id": 226,
"fromDomain": 97,
"host": "example.com",
"type": "MX",
"value": "mx.email.cm.com.",
"isValid": false,
"purpose": "receiving",
"priority": 10,
"dnsStatus": 3
}
]
}
Error Responses
| Status | Message | Cause |
|---|---|---|
| 400 | Unable to fetch DNS records | The records could not be read. |
| 500 | Unable to fetch DNS records | Unexpected failure while reading. |
Delete Domain
Remove a domain configuration and all associated DNS records.
Request Header
DELETE https://api.cm.com/email/configuration/v1/configuration/accounts/{logicalAccountId}/domains/{domainId}
| Parameter | Type | Required | Description |
|---|---|---|---|
| logicalAccountId | UUID | Yes | The logical account identifier |
| domainId | integer | Yes | The domain identifier to delete |
Response Body
Successful Response (200)
{
"status": 200,
"message": "Success",
"success": true
}
Error Responses
| Status | Message | Cause |
|---|---|---|
| 400 | Invalid request. Please check your input. | logicalAccountId is empty. |
| 400 | Unable to delete the domain | No domain with this domainId exists on the account, or the delete failed. |
| 404 | The requested resource was not found. | domainId is 0 or negative. |
Verify Domain Configuration
Check the DNS records of every capability that is enabled on the domain. Sending is checked through its CNAME records, receiving through its MX record. To check one capability only, see Verify a capability.
Request
POST https://api.cm.com/email/configuration/v1/dns/accounts/{logicalAccountId}/verify?domain={domain}
Content-Type: application/json
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| logicalAccountId | path | UUID | Yes | The logical account identifier |
| domain | query | string | Yes | Domain name to verify (e.g., "example.com") |
| Header Name | Type | Required | Description |
|---|---|---|---|
| Authorization | string | Yes | Valid authorization token |
Response Body
Successful Response (200)
dnsEntries lists every record on the domain: the three sending CNAMEs and the receiving MX. Each entry has isValid and a status (1 not verified yet, 2 verified, 3 verification ran and failed).
{
"status": 200,
"message": "Success",
"success": true,
"dnsEntries": [
{
"host": "cm50025f6ad4fd4a239e2ebbee1cf67d2b.example.com",
"value": "50025f6ad4fd4a239e2ebbee1cf67d2b.email.cm.com.",
"isValid": true,
"type": "CNAME",
"purpose": "sending",
"priority": null,
"status": 2
},
{
"host": "cm150025f6ad4fd4a239e2ebbee1cf67d2b._domainkey.example.com",
"value": "50025f6ad4fd4a239e2ebbee1cf67d2bcm1._domainkey.email.cm.com.",
"isValid": true,
"type": "CNAME",
"purpose": "sending",
"priority": null,
"status": 2
},
{
"host": "cm250025f6ad4fd4a239e2ebbee1cf67d2b._domainkey.example.com",
"value": "50025f6ad4fd4a239e2ebbee1cf67d2bcm2._domainkey.email.cm.com.",
"isValid": false,
"type": "CNAME",
"purpose": "sending",
"priority": null,
"status": 3
},
{
"host": "example.com",
"value": "mx.email.cm.com.",
"isValid": false,
"type": "MX",
"purpose": "receiving",
"priority": 10,
"status": 3
}
]
}
A 200 means the check ran, not that the domain is valid. Read isValid on each entry. Re-run the call after DNS has propagated.
Error Responses
Failures return dnsEntries: [] and the message unable to verify domain. The status and HTTP code identify the cause.
| Status | Cause |
|---|---|
| 400 | Domain is blank or the request is invalid. |
| 401 | Missing or invalid credentials or permission. |
| 404 | The domain is not registered on this account. |
| 409 | Receiving is already enabled and verified for this domain under another account. See One owner per domain. |
| 500 | The verification result could not be stored. |
Receive Email on a Domain
Receiving adds one MX record that routes mail for any address at the domain to CM.com. The endpoints in this section enable or disable each capability and verify it. They use the same base URL and authentication as the rest of this page. For what happens to a message once it arrives, see Receive Emails.
The two capabilities are independent. Enabling receiving does not require you to re-verify sending, and only the MX record is checked for receiving.
Use a dedicated subdomain if the domain already receives mail. CM.com must be the most preferred MX for the domain, so adding it to a domain that hosts your regular mailboxes would redirect that mail. Register a subdomain such as
inbound.example.comfor inbound mail instead.
Enable or disable a capability
Enable or disable receiving
PUT https://api.cm.com/email/configuration/v1/configuration/accounts/{logicalAccountId}/domains/{domain}/receiving?enabled=true
Enable or disable sending
PUT https://api.cm.com/email/configuration/v1/configuration/accounts/{logicalAccountId}/domains/{domain}/sending?enabled=true
Parameters
Both calls take the same parameters.
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
logicalAccountId | path | UUID | Yes | The logical account identifier. |
domain | path | string | Yes | Domain name, max 253 characters. Matched exactly (case-sensitive) against the stored domain, which is lowercase. |
enabled | query | boolean | Yes | true to enable, false to disable. Always send it explicitly. |
Sending is enabled by default for new domains; receiving is disabled. Toggling one capability leaves the other untouched. Enabling a capability triggers a best-effort DNS verification straight away, so the returned records may already be valid. A failure of that check does not fail the request.
Disabling a capability stops its DNS records counting as valid. Disabling receiving therefore invalidates the MX record.
Successful response (200)
data holds the updated domain (single element). status is 1 not verified yet, 2 verified, 3 verification ran and failed.
{
"success": true,
"status": 200,
"message": "Success",
"data": [
{
"id": 97,
"accountId": "50025f6a-d4fd-4a23-9e2e-bbee1cf67d2b",
"domain": "example.com",
"isValid": false,
"status": 1,
"sendingEnabled": true,
"receivingEnabled": true,
"dnsRecords": [
{ "host": "example.com", "type": "MX", "value": "mx.email.cm.com.", "purpose": "receiving", "priority": 10, "dnsStatus": 1 }
]
}
]
}
Error responses
| Status | Message | Cause |
|---|---|---|
| 400 | Domain length exceeded the max limit | domain blank or longer than 253 characters. |
| 401 | Unauthorized | Missing or invalid credentials / permission. |
| 404 | Domain not found | Domain is not registered on this account. |
| 409 | Receiving is already enabled and verified for this domain under another account. Disable it there before enabling it here. | Ownership rule, see One owner per domain. receiving with enabled=true only. |
| 500 | Something went wrong while toggling domain capabilities | Write failed. |
Verify a capability
The Verify Domain Configuration call checks every capability enabled on the domain. To check one capability, add it to the path:
POST https://api.cm.com/email/configuration/v1/dns/accounts/{logicalAccountId}/verify/{capability}?domain={domain}
| Parameter | In | Description |
|---|---|---|
logicalAccountId | path | The logical account identifier (UUID). |
capability | path | sending, receiving or all (case-insensitive). Anything else returns 400 Invalid capability value. |
domain | query | Domain name. Query parameter only, max 253 characters. |
Successful response (200)
Same dnsEntries shape as the plain verify call, with purpose, priority and status added to each entry:
{
"status": 200,
"message": "Success",
"success": true,
"dnsEntries": [
{ "host": "example.com", "value": "mx.email.cm.com.", "isValid": true, "type": "MX", "purpose": "receiving", "priority": 10, "status": 2 }
]
}
Error responses
Same statuses as the errors under Verify Domain Configuration, with these messages: 400 Domain name is invalid or exceeds the max limit. unable to verify domain, 404 No DNS records found for the specified domain, 500 Invalid domain host validity.. The 409 is the one-owner rule.
A change in the domain's overall verified state also sends a Domain status change notification email to the account.
One owner per domain
Inbound routing is keyed on the domain's MX, so a delivered message must belong to exactly one account. At most one account can hold enabled and verified receiving for a given domain (compared case-insensitively).
- Enabling receiving (
PUT …/receiving?enabled=true) returns 409 Conflict straight away if another account already holds enabled and verified receiving for the domain. - Verifying receiving (
POST …/verify/receiving) returns the same 409 if another account became the owner in the meantime. Only one account can ever be verified. - To move a domain, disable receiving on the current owner first, then enable and verify it on the new account.
Automatic re-verification
All domains are re-checked weekly, only for their enabled capabilities. A change in a domain's overall verified state emails the account. A check that cannot complete is skipped and leaves the stored state unchanged.
In the Email App
The domain detail page has a Sending Enabled and a Receiving Enabled toggle. The MX record appears in the receiving table with its priority. If the app detects a conflicting MX record it shows a warning, and a 409 from the ownership rule is reported as "Another account has already enabled and verified receiving for this domain". The Verify Domain button checks every enabled capability. Verifying one capability on its own is available through the API only.
Receiving setup checklist
- Add the domain.
- Add the MX record returned in the API response to your domain's DNS.
- Wait for DNS propagation, then call
POST …/verify/receiving?domain=…untilisValidistrue. - Register an inbound webhook for the domain.
- Send a test message to any address at the domain and check the Receiving page in the Email App.
Domain Verification Process
- Add Domain: Submit your account ID and the domain name
- DNS Records Generated: System automatically creates three CNAME records for sending and one MX record for receiving. Add the MX record to your DNS if you want to receive email on this domain
- Add DNS Records: Add the generated CNAME records to your domain's DNS settings
- Wait for Propagation: Allow time for DNS changes to propagate (5 minutes to 48 hours)
- Verify Domain: Use the verification endpoint to check DNS record configuration
- Check Results: Review verification response to see which records are valid
- Retry if Needed: Re-run verification after additional propagation time if some records show as invalid
- Email Sending: Domain is ready for email sending once all records show
"isValid": true
To receive inbound email on the domain, see Receive Email on a Domain and Receive Emails.
Common Issues and Solutions
| Issue | Cause | Solution |
|---|---|---|
All records show isValid: false | DNS records not yet added or propagated | Wait for DNS propagation (5 min - 48 hours) and retry |
| Some records valid, others invalid | Partial DNS configuration or caching | Check DNS provider settings and wait for full propagation |
| Verification endpoint returns 404 | Domain not found in account | Ensure domain was properly added to account first |
| Verification endpoint returns 409 | Another account owns receiving for the domain | See One owner per domain |
Example Use Cases
Register Company Domain
Setting up a primary company domain for email sending:
{
"accountId": "50025f6a-d4fd-4a23-9e2e-bbee1cf67d2b",
"domain": "company.com"
}
Add Subdomain for Marketing
Adding a subdomain specifically for marketing campaigns:
{
"accountId": "50025f6a-d4fd-4a23-9e2e-bbee1cf67d2b",
"domain": "marketing.company.com"
}
Multi-Domain Setup
Managing multiple domains for different business units:
- Main Website:
company.com - Support Portal:
support.company.com - Marketing Campaigns:
promo.company.com - Customer Portal:
portal.company.com
Each domain receives the same three sending CNAME records (with domain-specific hostnames) plus one receiving MX record, all pointing to the same account-specific email infrastructure, ensuring consistent email delivery across all business units.