Domains
Add and verify sending domains: DKIM, return path, SPF and DMARC records.
You can only send from domains you have verified in your workspace. Verification proves you control the domain and sets up the DNS records receiving servers use to authenticate your mail. All domain endpoints require a full_access key.
Create a domain
/api/v1/domainsBody
namestringrequired- The domain or subdomain, e.g.
example.comormail.example.com(3–253 characters). IP addresses, names without a TLD, Bytesms' own domains and consumer mailbox domains (gmail.com, …) are refused with422 invalid_domain/reserved_domain. regionstringdefaultap-southeast-7- Sending region:
ap-southeast-7(Thailand),ap-southeast-1(Singapore) oreu-central-1(Frankfurt). See Regions. A region without an available sending server falls back to the default region — checkregionin the response. custom_return_pathstringdefaultsend- Label of the return-path subdomain (
<label>.<domain>). One lowercase DNS label: a–z, 0–9 and-, 1–63 characters, not starting or ending with-.www,mail,smtp,mx,imap,pop,pop3,autodiscoverandautoconfigare reserved.
# Create a domain
curl -X POST 'https://api.bytesms.com/api/v1/domains' \
-H 'Authorization: Bearer tp_live_xxxxxxxxx' \
-H 'Content-Type: application/json' \
-d '{"name":"example.com","region":"ap-southeast-7"}'{
"id": "cmg4jz1pb0000l8v9a6c3e2kf",
"name": "example.com",
"status": "not_started",
"region": "ap-southeast-7",
"created_at": "2026-09-28T08:00:00.000Z",
"custom_return_path": "send",
"records": [
{
"record": "DKIM",
"name": "bytesms._domainkey.example.com",
"type": "TXT",
"ttl": "Auto",
"status": "not_started",
"value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqhkiG9w0BAQEFAAOCAQ8AMIIBCgKCAQEA…"
},
{
"record": "RETURN_PATH",
"name": "send.example.com",
"type": "CNAME",
"ttl": "Auto",
"status": "not_started",
"value": "mta.bytesms.com"
},
{
"record": "SPF",
"name": "example.com",
"type": "TXT",
"ttl": "Auto",
"status": "not_started",
"value": "v=spf1 include:_spf.bytesms.com ~all"
},
{
"record": "DMARC",
"name": "_dmarc.example.com",
"type": "TXT",
"ttl": "Auto",
"status": "not_started",
"value": "v=DMARC1; p=none; rua=mailto:[email protected]"
}
]
}409 domain_in_use— the domain is verified in another workspace.409 domain_pending_elsewhere— another workspace added it less than 72 hours ago and hasn't verified it yet.403 plan_limit_exceeded(code: domain_limit_reached) — your plan's domain limit is reached.
DNS records
Publish the records from the records array at your DNS provider exactly as returned — names and values differ per domain and region.
| record | Type | Required | Purpose |
|---|---|---|---|
DKIM | TXT | Yes | Public key at bytesms._domainkey.<domain>. Every message is signed with the matching private key as d=<your domain>, which is what DMARC alignment needs. |
RETURN_PATH | CNAME | Yes* | send.<domain> (or your custom label) → the region's bounce host, e.g. mta.bytesms.com. The envelope sender of your mail lives on this subdomain, so SPF passes aligned with your domain and bounces flow back to Bytesms. |
SPF | TXT | Alternative | include:_spf.bytesms.comon the domain itself. Only needed if you can't publish the return-path CNAME; merge it into an existing SPF record instead of adding a second one. |
DMARC | TXT | Recommended | _dmarc.<domain>. Start with p=none and a rua report address, then tighten to quarantine/reject once reports look clean. Gmail and Yahoo require a DMARC record for bulk senders. |
* A domain becomes verified when DKIM resolves andeither the return-path CNAME or SPF does. Each record's status shows the last check result, so a verified domain can still list an optional record as not_started.
Changing the return-path label
One-click setup (Domain Connect)
If your DNS provider supports the Domain Connect protocol with the Bytesms template, the dashboard shows a one-click setup button on the domain page that publishes the records for you after you approve them at your provider. Otherwise the dashboard shows the records to copy manually.
Verification statuses
| status | Meaning |
|---|---|
not_started | Created; verification hasn't run yet. |
pending | Checking DNS. Re-checked automatically every few minutes. |
verified | Ready to send. |
temporary_failure | A verified domain's records stopped resolving; it is re-checked and returns to verified once they resolve again. |
failed | Records were not found within 72 hours (or stayed missing). Fix DNS and verify again. |
Status changes are sent as domain.updated webhook events.
Verify a domain
/api/v1/domains/{domain_id}/verifyStarts (or re-runs) DNS verification. Poll the domain or listen for domain.updated for the result.
# Verify a domain curl -X POST 'https://api.bytesms.com/api/v1/domains/cmg4jz1pb0000l8v9a6c3e2kf/verify' \ -H 'Authorization: Bearer tp_live_xxxxxxxxx'
{
"object": "domain",
"id": "cmg4jz1pb0000l8v9a6c3e2kf"
}Retrieve a domain
/api/v1/domains/{domain_id}Returns the domain with its records, like the create response plus object: "domain".
# Retrieve a domain curl -X GET 'https://api.bytesms.com/api/v1/domains/cmg4jz1pb0000l8v9a6c3e2kf' \ -H 'Authorization: Bearer tp_live_xxxxxxxxx'
List domains
/api/v1/domains# List domains curl -X GET 'https://api.bytesms.com/api/v1/domains' \ -H 'Authorization: Bearer tp_live_xxxxxxxxx'
{
"object": "list",
"has_more": false,
"data": [
{
"id": "cmg4jz1pb0000l8v9a6c3e2kf",
"name": "example.com",
"status": "verified",
"region": "ap-southeast-7",
"created_at": "2026-09-28T08:00:00.000Z"
}
]
}Delete a domain
/api/v1/domains/{domain_id}Removes the domain from the workspace and from its sending server, including its DKIM key (adding it again later creates a new key, so the DKIM record must be updated). If the sending server can't be reached, nothing is deleted and the call fails with 503 — retry it.
# Delete a domain curl -X DELETE 'https://api.bytesms.com/api/v1/domains/cmg4jz1pb0000l8v9a6c3e2kf' \ -H 'Authorization: Bearer tp_live_xxxxxxxxx'
{
"object": "domain",
"id": "cmg4jz1pb0000l8v9a6c3e2kf",
"deleted": true
}