Transactional domains
A transactional domain is a sending subdomain of one of your verified domains, such as mail.example.com. Transactional senders send from it once its DNS records are verified. Mail routing on your root domain does not change.
Last updated
Before you start
- The root domain must already be verified in Shipmail. List yours with
GET /v1/domains. - Writes need
domains:write, and the key must act for an Owner or Admin with access to every mailbox. - A key limited to some domains reaches only the subdomains of those domains. A key limited to mailboxes reaches none.
- Setup steps have their own limits per key: 20 creates and 20 deletes per hour, and 120 checks per 10 minutes. Past them the API answers
429.
The transactional domain object
{
"object": "transactional_domain",
"id": "txdom_0123456789abcdefghjkmnpq",
"name": "mail.example.com",
"root_domain": "example.com",
"status": "pending",
"mail_from_domain": "mail.mail.example.com",
"dns_records": [
{
"key": "dkim",
"type": "TXT",
"host": "shipmail._domainkey.mail.example.com",
"value": "v=DKIM1; k=rsa; p=MIIBIjANBgkqh...",
"priority": null,
"ttl": 300,
"description": "Signs your transactional email so inboxes trust it.",
"status": "pending"
}
],
"verified_at": null,
"created_at": "2026-11-08T09:00:00.000Z"
}| Field | Type | Description |
|---|---|---|
| id | string | Starts with txdom_. |
| name | string | The sending subdomain, such as mail.example.com. |
| root_domain | string | The verified domain it belongs to. |
| status | string | pending, verifying, verified or failed. Senders need verified. |
| mail_from_domain | string | The return path that receives bounce reports. It is not an inbox. |
| dns_records | array | The records to publish, each with key, type, host, value, priority, ttl, description and status (pending, verified or failed). Empty while setup has not finished. |
| verified_at | string or null | When every record was first verified. |
| created_at | string | ISO 8601 timestamp. |
dns_records has three entries: the DKIM key (dkim), and the MX and SPF records of the return path (mail_from_mx and mail_from_spf). Publish each one exactly as returned. The transactional email guide explains what each record does.
List transactional domains
/v1/transactional-domainsscope domains:readtier readReturns { "object": "list", "data": [...] } with every sending subdomain the key can reach, without pagination.
Create a transactional domain
/v1/transactional-domainsscope domains:writetier write{
"root_domain": "example.com",
"subdomain": "mail"
}root_domain is a verified domain of your organization. subdomain is one DNS label: mail gives mail.example.com. Returns 201 with the domain and the DNS records to publish.
If setup stops part way, the domain comes back with an empty dns_records, or the request fails with transactional_domain_setup_failed. Send the same request again: it resumes the setup instead of creating a second domain.
Retrieve a transactional domain
/v1/transactional-domains/:idscope domains:readtier readReturns the domain with the status Shipmail last recorded. Shipmail also checks pending domains in the background.
Verify a transactional domain
/v1/transactional-domains/:id/verifyscope domains:writetier verificationChecks the DNS records now and returns the domain with the status of each record. Once every record is verified, status becomes verified and you can create senders on it. DNS usually updates in a few minutes, sometimes up to an hour. The verification tier allows 1 request per minute, so poll no faster than that.
Delete a transactional domain
/v1/transactional-domains/:idscope domains:writetier writeReturns 204. Shipmail stops sending from the subdomain and deletes its DKIM key; you can then delete its DNS records. Deleting is refused with 409 while senders use the subdomain. If removal stops part way, send the same request again.
Errors
Errors use the standard error envelope. Branch on details[0].code, not on the message.
| Status | details[].code | When |
|---|---|---|
| 422 | transactional_subdomain_invalid | subdomain is not one DNS label. |
| 404 | transactional_root_domain_not_verified | root_domain is not a verified domain of your organization. |
| 409 | transactional_subdomain_unavailable | The subdomain is already in use. Choose another one. |
| 500 | transactional_domain_setup_failed | Setup stopped part way. Send the same request again to resume. |
| 404 | transactional_domain_not_found | No sending subdomain with this id, or the API key cannot reach its root domain. |
| 409 | transactional_domain_setup_incomplete | Verify was called before setup finished. Create it again to resume. |
| 500 | transactional_domain_check_failed | The DNS check failed. Try again in a minute. |
| 409 | transactional_domain_has_senders | Delete was refused because senders still use the subdomain. |
| 409 | transactional_domain_abuse_hold | Delete was refused while the organization is under an abuse hold. |
| 500 | transactional_domain_remove_failed | Removal stopped part way. Send the same request again. |
| 409 | mailbox_writes_paused | Changes are paused for your organization. Try again later. |