API referenceDomains

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.

Endpoint
POST https://api.dairo.app/v1/domains

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

cURL
curl -X POST "https://api.dairo.app/v1/domains" \
  -H "Authorization: Bearer $DAIRO_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "domain": "example.com"
  }'

Headers

NameTypeRequiredDescription
Idempotency-KeystringnoOptional idempotency key for safe retries of side-effecting operations. (max length 128)

Body

Required, application/json: CreateDomainRequest.

FieldTypeRequiredDescription
domainstringyes

Response

201 Created. Body: application/json, Domain.

FieldTypeRequiredDescription
object"domain"yes
idstring (uuid)yes
domainstringyes
status"pending", "verified", "failed"yes
verifiedAtstring (date-time) or nullno
regionstringyes
recordsarray of DnsRecordyes
type"custom", "included", "system"no
isIncludedbooleanno
isDeletablebooleanno
isSystembooleannoOnly on the shared dairo.app system domain.
isReadOnlybooleannoOnly on the shared dairo.app system domain.
receiving"active", "pending"noOnly on the verify response: whether the domain receives mail (it does exactly when verified).
201
{
  "object": "domain",
  "id": "3fa85f64-5717-4562-b3fc-2c963f66afa6",
  "domain": "orin-ai.app",
  "status": "pending",
  "verifiedAt": "2026-10-19T09:30:00Z",
  "region": "eu-north-1",
  "records": [
    {
      "type": "CNAME",
      "host": "string",
      "value": "string",
      "priority": null,
      "status": "pending"
    }
  ],
  "type": "custom",
  "isIncluded": true,
  "isDeletable": true,
  "isSystem": true,
  "isReadOnly": true,
  "receiving": "active"
}

Errors

Every error has the same body, {"error": {"type", "code", "message", "param"}}; branch on code. Errors lists every code.

StatusMeaning
400The request is malformed or a value is invalid (invalid_request, invalid_domain, idempotency_key_mismatch).
401The API key is missing or invalid.
403The key lacks the scope this endpoint needs (scope_missing) or may not do this (not_permitted).
404No such resource in this account (resource_not_found).
422The request is well-formed but a field failed validation (validation_failed).
429Rate limit, plan limit, budget or spend cap reached (rate_limited, plan_limit_reached, budget_exceeded, spend_cap_reached).
500An unexpected error; retry with backoff, then contact support (internal_error).

On this page