Create a domain and its DNS records
Registers a domain you own for authenticated sending and inbound receiving, and returns the created domain object with the records array to publish in DNS.
Registers a domain you own for authenticated sending and inbound receiving, and returns the created domain object with the records array to publish in DNS. Those records are DKIM CNAME records, an MX and an SPF TXT record on the mail. sending subdomain, an MX record on the root domain for receiving replies, and a DMARC TXT record on _dmarc; each record reports its own status of pending or configured. A new domain starts at status: "pending" and stays there until you publish the records and it passes a recheck — see verify a domain. The call is idempotent on the domain name: re-creating a domain you already own returns the existing record instead of erroring, so a retry is safe without an Idempotency-Key. A domain another account has verified, or claimed within the last 72 hours, is refused with a 409; an older claim that never verified and has no inboxes is released to you, so nobody can hold a domain they cannot prove. dairo.app cannot be created because it is included with every account. Only a key whose creator is an organization owner or admin may add domains, and a key restricted to specific inboxes is refused with a 403. Requires domains:write, counts against your plan's domain limit (a 429 once reached), and is rate-limited to 10 create calls per hour.
Scope: domains:write. Send the API key as a bearer token; Scopes lists what each one reaches.
Request
Headers
| Name | Type | Required | Description |
|---|---|---|---|
Idempotency-Key | string | no | Optional idempotency key for safe retries of side-effecting operations. (max length 128) |
Body
Required, application/json: CreateDomainRequest.
| Field | Type | Required | Description |
|---|---|---|---|
domain | string | yes |
Response
201 Created. Body: application/json, Domain.
| Field | Type | Required | Description |
|---|---|---|---|
object | "domain" | yes | |
id | string (uuid) | yes | |
domain | string | yes | |
status | "pending", "verified", "failed" | yes | |
verifiedAt | string (date-time) or null | no | |
region | string | yes | |
records | array of DnsRecord | yes | |
type | "custom", "included", "system" | no | |
isIncluded | boolean | no | |
isDeletable | boolean | no | |
isSystem | boolean | no | Only on the shared dairo.app system domain. |
isReadOnly | boolean | no | Only on the shared dairo.app system domain. |
receiving | "active", "pending" | no | Only on the verify response: whether the domain receives mail (it does exactly when verified). |
Errors
Every error has the same body, {"error": {"type", "code", "message", "param"}}; branch on code. Errors lists every code.
| Status | Meaning |
|---|---|
400 | The request is malformed or a value is invalid (invalid_request, invalid_domain, idempotency_key_mismatch). |
401 | The API key is missing or invalid. |
403 | The key lacks the scope this endpoint needs (scope_missing) or may not do this (not_permitted). |
404 | No such resource in this account (resource_not_found). |
422 | The request is well-formed but a field failed validation (validation_failed). |
429 | Rate limit, plan limit, budget or spend cap reached (rate_limited, plan_limit_reached, budget_exceeded, spend_cap_reached). |
500 | An unexpected error; retry with backoff, then contact support (internal_error). |