[Skip to content](/content/docs/reference/api/domains#nd-page/index.html) [Skip to content](/content/docs/reference/api/domains#nd-page/index.html)

\[01/16\]List Domains

| Method | Path | Summary |
| --- | --- | --- |
| `GET` | `/v0/domains` | [List Domains](/content/docs/reference/api/domains#list-domains/index.html) |
| `POST` | `/v0/domains` | [Create Domain](/content/docs/reference/api/domains#create-domain/index.html) |
| `GET` | `/v0/domains/{domain_id}` | [Get Domain](/content/docs/reference/api/domains#get-domain/index.html) |
| `PATCH` | `/v0/domains/{domain_id}` | [Update Domain](/content/docs/reference/api/domains#update-domain/index.html) |
| `DELETE` | `/v0/domains/{domain_id}` | [Delete Domain](/content/docs/reference/api/domains#delete-domain/index.html) |
| `GET` | `/v0/domains/{domain_id}/domain-connect` | [Get Domain Connect Setup](/content/docs/reference/api/domains#get-domain-connect-setup/index.html) |
| `POST` | `/v0/domains/{domain_id}/verify` | [Verify Domain](/content/docs/reference/api/domains#verify-domain/index.html) |
| `GET` | `/v0/domains/{domain_id}/zone-file` | [Get Zone File](/content/docs/reference/api/domains#get-zone-file/index.html) |
| `GET` | `/v0/pods/{pod_id}/domains` | [List Domains in Pod](/content/docs/reference/api/domains#list-domains-in-pod/index.html) |
| `POST` | `/v0/pods/{pod_id}/domains` | [Create Domain in Pod](/content/docs/reference/api/domains#create-domain-in-pod/index.html) |
| `GET` | `/v0/pods/{pod_id}/domains/{domain_id}` | [Get Domain in Pod](/content/docs/reference/api/domains#get-domain-in-pod/index.html) |
| `PATCH` | `/v0/pods/{pod_id}/domains/{domain_id}` | [Update Domain in Pod](/content/docs/reference/api/domains#update-domain-in-pod/index.html) |
| `DELETE` | `/v0/pods/{pod_id}/domains/{domain_id}` | [Delete Domain in Pod](/content/docs/reference/api/domains#delete-domain-in-pod/index.html) |
| `GET` | `/v0/pods/{pod_id}/domains/{domain_id}/domain-connect` | [Get Domain Connect Setup in Pod](/content/docs/reference/api/domains#get-domain-connect-setup-in-pod/index.html) |
| `POST` | `/v0/pods/{pod_id}/domains/{domain_id}/verify` | [Verify Domain in Pod](/content/docs/reference/api/domains#verify-domain-in-pod/index.html) |
| `GET` | `/v0/pods/{pod_id}/domains/{domain_id}/zone-file` | [Get Zone File in Pod](/content/docs/reference/api/domains#get-zone-file-in-pod/index.html) |

## [List Domains](/content/docs/reference/api/domains\#list-domains/index.html)

http

```
GET /v0/domains
```

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_read`.

#### [Query parameters](/content/docs/reference/api/domains\#query-parameters/index.html)

FieldDescription

`limit``integer`

Maximum number of items to return. Default 50, maximum 500; larger values are capped.

`page_token``string`

next\_page\_token from the previous page.

`ascending``boolean`

Sort oldest first.

#### [Response](/content/docs/reference/api/domains\#response/index.html)

**200** A page of domains (`application/json`)

FieldDescription

`count``integer`Required

Number of items returned.

`limit``integer`

Maximum number of items per page. Default 50, maximum 500; larger values are capped.

`next_page_token``string`

Page token for pagination. Absent on the last page.

`domains` [DomainItem\[\]](/content/docs/reference/api/objects#domainitem/index.html) Required

Ordered by created\_at, newest first unless ascending is set.

Each item of `domains` is a [DomainItem](/content/docs/reference/api/objects#domainitem/index.html):

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

Verification status, as on Domain.

`reason``string`

Why the domain is not verified yet, as on Domain.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish, as on Domain.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

#### [Errors](/content/docs/reference/api/domains\#errors/index.html)

| Status | Meaning |
| --- | --- |
| `400` | Invalid request: error.type is validation and error.param names the field. |
| `401` | Missing, invalid, expired or revoked credential. |
| `403` | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `500` | Unexpected server error. |

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example/index.html)

Request

```
curl "https://api.machinemail.dev/v0/domains" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

```
{
  "count": 1,
  "limit": 50,
  "next_page_token": "eyJvIjo1MH0",
  "domains": [\
    {\
      "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",\
      "domain_id": "dom_01k6x3d5kq0000g3q9sx5b8j0m",\
      "domain": "example.com",\
      "feedback_enabled": false,\
      "inbound_enabled": false,\
      "subdomains_enabled": false,\
      "tracking_enabled": false,\
      "client_id": "my-client-id",\
      "updated_at": "2026-10-01T12:00:00.000Z",\
      "created_at": "2026-10-01T12:00:00.000Z",\
      "status": "NOT_STARTED",\
      "reason": "string",\
      "records": [\
        {\
          "type": "TXT",\
          "name": "Production",\
          "value": "string",\
          "status": "MISSING",\
          "priority": 1,\
          "reason": "string",\
          "purpose": "inbound",\
          "required": false\
        }\
      ],\
      "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",\
      "catch_all": false,\
      "catch_all_ttl_seconds": 1,\
      "nameservers": ["string"],\
      "dns_provider": "cloudflare",\
      "dns_provider_url": "https://example.com",\
      "domain_connect": {\
        "supported": false,\
        "provider_name": "string",\
        "apply_url": "https://example.com"\
      },\
      "verified_at": "2026-10-01T12:00:00.000Z",\
      "last_checked_at": "2026-10-01T12:00:00.000Z"\
    }\
  ]
}
```

## [Create Domain](/content/docs/reference/api/domains\#create-domain/index.html)

http

```
POST /v0/domains
```

Registers the domain and returns the DNS records to publish (`status: NOT_STARTED`). Publish them, then call Verify Domain. A background worker re-checks `PENDING`, `INVALID` and `VERIFYING` domains about every 5 minutes until 7 days after creation; a `NOT_STARTED` domain is only checked by Verify Domain. A domain that is never verified is removed 14 days after it was added, together with its inboxes and the mail in them; owners and admins of the organization are emailed at least 3 days before. A domain that was verified once is never removed this way.

A domain can be registered by one organization only (`409`), and the shared domain cannot be added (`409`). Inbox-scoped credentials cannot add domains (`403`).

`allow_conflicting_provider`, `subdomains_enabled` and `tracking_enabled` are not supported.

`502 upstream_error` when the email provider cannot register the domain (for example its domain capacity is reached, or it is rate limiting registrations): nothing is created.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_create`.

#### [Request body](/content/docs/reference/api/domains\#request-body/index.html)

Content type: `application/json`.

FieldDescription

`domain``string`Required

The domain name, for example example.com. Cannot be the shared domain or a domain another organization registered.

`feedback_enabled``boolean`

Stored and returned; has no effect. Default false.

`inbound_enabled``boolean`

Receive email for this domain. Default true. false makes it send-only (the inbound MX record is not required).

`client_id``string`

Idempotency key: a create with a client\_id already used in the organization returns that domain with 200, or 409 when that domain is outside the pod of the API key or route.

`pod_id``string`

Pod to create the domain in. Defaults to the credential pod or the organization default pod. A pod-scoped credential can only name its own pod.

`catch_all``boolean`

Create an inbox for any address at the domain that receives mail. Default false.

`catch_all_ttl_seconds``integer | null`

Make inboxes created by catch-all ephemeral with this TTL. null or absent: permanent.

#### [Response](/content/docs/reference/api/domains\#response-1/index.html)

**200** A domain with this client\_id already exists; it is returned unchanged. (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

NOT\_STARTED until the first verify, then VERIFIED when every required record is valid, INVALID when a required record has the wrong value, otherwise PENDING. For domains whose email provider reports its own verdict (Amazon SES): VERIFYING while every required record checks out but the provider has not confirmed them yet, and FAILED when the provider gave up (reason says why).

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

**201** Created (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

#### [Errors](/content/docs/reference/api/domains\#errors-1/index.html)

| Status | Meaning |
| --- | --- |
| `400` | Invalid request: error.type is validation and error.param names the field. |
| `401` | Missing, invalid, expired or revoked credential. |
| `402` | Free plan: the organization already has its 1 custom domain (limit\_key: “custom\_domains”). Paid plans can add domains past their allowance (billed as extra). |
| `403` | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `409` | Conflicts with an existing resource. |
| `500` | Unexpected server error. |
| `502` | The email provider refused or failed the send (error.type is upstream\_error). Nothing was sent and no message was stored. error.message says why: a rejected message or recipient is final, and so is a used-up sending quota until it resets; a throttled or unavailable provider can be retried later. A scheduled draft whose send fails this way is marked send\_status: failed, unless the provider could not take mail for now (throttled, sending paused, quota used up, or unavailable): it stays scheduled and is retried. |

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-1/index.html)

Request

```
curl -X POST "https://api.machinemail.dev/v0/domains" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "domain": "example.com",
  "feedback_enabled": false
}'
```

Response 200

```
{
  "pod_id": "pod_01k6x2m9qd0001b8j4mr0w3d5f",
  "domain_id": "dom_01k6x3d5kq0000g3q9sx5b8j0m",
  "domain": "example.com",
  "feedback_enabled": false,
  "inbound_enabled": false,
  "subdomains_enabled": false,
  "tracking_enabled": false,
  "client_id": "my-client-id",
  "updated_at": "2026-10-01T12:00:00.000Z",
  "created_at": "2026-10-01T12:00:00.000Z",
  "status": "NOT_STARTED",
  "reason": "string",
  "records": [\
    {\
      "type": "TXT",\
      "name": "Production",\
      "value": "string",\
      "status": "MISSING",\
      "priority": 1,\
      "reason": "string",\
      "purpose": "inbound",\
      "required": false\
    }\
  ],
  "organization_id": "org_01k6x2m9qd0000a7h3kq9v2c4e",
  "catch_all": false,
  "catch_all_ttl_seconds": 1,
  "nameservers": ["string"],
  "dns_provider": "cloudflare",
  "dns_provider_url": "https://example.com",
  "domain_connect": {
    "supported": false,
    "provider_name": "string",
    "apply_url": "https://example.com"
  },
  "verified_at": "2026-10-01T12:00:00.000Z",
  "last_checked_at": "2026-10-01T12:00:00.000Z"
}
```

## [Get Domain](/content/docs/reference/api/domains\#get-domain/index.html)

http

```
GET /v0/domains/{domain_id}
```

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_read`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters/index.html)

FieldDescription

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-2/index.html)

**200** The domain (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

#### [Errors](/content/docs/reference/api/domains\#errors-2/index.html)

| Status | Meaning |
| --- | --- |
| `401` | Missing, invalid, expired or revoked credential. |
| `403` | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404` | Not found. Also returned for resources outside the credential scope. |
| `500` | Unexpected server error. |

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-2/index.html)

Request

```
curl "https://api.machinemail.dev/v0/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

## [Update Domain](/content/docs/reference/api/domains\#update-domain/index.html)

http

```
PATCH /v0/domains/{domain_id}
```

Fields you omit are unchanged. `subdomains_enabled` and `tracking_enabled` are not supported.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_update`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-1/index.html)

FieldDescription

`domain_id``string`Required

ID of the domain.

#### [Request body](/content/docs/reference/api/domains\#request-body-1/index.html)

Content type: `application/json`.

FieldDescription

`feedback_enabled``boolean`

Stored and returned; has no effect.

`inbound_enabled``boolean`

Receive email for this domain. false makes the inbound MX record optional and re-evaluates the status.

`catch_all``boolean`

Create an inbox for any address at the domain that receives mail.

`catch_all_ttl_seconds``integer | null`

TTL of inboxes created by catch-all from now on. null makes them permanent.

#### [Response](/content/docs/reference/api/domains\#response-3/index.html)

**200** The updated domain (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

#### [Errors](/content/docs/reference/api/domains\#errors-3/index.html)

| Status | Meaning |
| --- | --- |
| `400` | Invalid request: error.type is validation and error.param names the field. |
| `401` | Missing, invalid, expired or revoked credential. |
| `403` | The credential lacks the permission or scope for this request (error.type forbidden), or MachineMail suspended the organization or its sending (account\_suspended: error.message says what still works; do not retry or re-register). |
| `404` | Not found. Also returned for resources outside the credential scope. |
| `500` | Unexpected server error. |

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-3/index.html)

Request

```
curl -X PATCH "https://api.machinemail.dev/v0/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "feedback_enabled": false
}'
```

Response 200

## [Delete Domain](/content/docs/reference/api/domains\#delete-domain/index.html)

http

```
DELETE /v0/domains/{domain_id}
```

Inboxes on the domain are not deleted.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_delete`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-2/index.html)

FieldDescription

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-4/index.html)

**200** Deleted (`application/json`)

FieldDescription

`ok``true`Required

#### [Errors](/content/docs/reference/api/domains\#errors-4/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-4/index.html)

Request

```
curl -X DELETE "https://api.machinemail.dev/v0/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

```
{
  "ok": true
}
```

## [Get Domain Connect Setup](/content/docs/reference/api/domains\#get-domain-connect-setup/index.html)

http

```
GET /v0/domains/{domain_id}/domain-connect
```

Discovers whether the domain’s DNS provider supports Domain Connect (TXT `_domainconnect.<zone>` and the provider’s `/v2/<zone>/settings`) and has onboarded the MachineMail template (`machinemail.dev`/`email`). When it has, `apply_url` is a signed synchronous-flow link (RS256, `key=_dck1`, `sig` last) that opens the provider with the outstanding MX, SPF, DKIM and DMARC records prefilled. Discovery is cached on the domain (6 h; provider errors 10 min) and re-run by Verify Domain.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_read`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-3/index.html)

FieldDescription

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-5/index.html)

**200** Domain Connect support for the domain (`application/json`)

FieldDescription

`supported``boolean`Required

The zone DNS provider supports Domain Connect and has the MachineMail template.

`provider_name``string`

Display name of the DNS provider.

`apply_url``string`

Signed link that opens the provider with the outstanding records prefilled. Absent when nothing is left to add.

`provider_id``string`

Domain Connect provider ID.

`url_sync_ux``string`

Base URL of the provider synchronous flow.

`width``integer`

Suggested popup width, in pixels.

`height``integer`

Suggested popup height, in pixels.

`reason``"no_domain_connect" | "provider_error" | "no_sync_flow" | "template_not_supported" | "records_not_templatable" | "already_configured" | "not_configured"`

Why one-click setup is not available, or already\_configured when nothing is left to add.

`checked_at``string (date-time)`Required

When discovery last ran.

#### [Errors](/content/docs/reference/api/domains\#errors-5/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-5/index.html)

Request

```
curl "https://api.machinemail.dev/v0/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m/domain-connect" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

```
{
  "supported": false,
  "provider_name": "string",
  "apply_url": "https://example.com",
  "provider_id": "string",
  "url_sync_ux": "string",
  "width": 1,
  "height": 1,
  "reason": "no_domain_connect",
  "checked_at": "2026-10-01T12:00:00.000Z"
}
```

## [Verify Domain](/content/docs/reference/api/domains\#verify-domain/index.html)

http

```
POST /v0/domains/{domain_id}/verify
```

Checks every DNS record now, updates `records[].status` and `status`, and re-runs Domain Connect discovery. A `domain.verified` event is emitted when the domain becomes `VERIFIED`.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_update`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-4/index.html)

FieldDescription

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-6/index.html)

**200** The domain after the check (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

#### [Errors](/content/docs/reference/api/domains\#errors-6/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-6/index.html)

Request

```
curl -X POST "https://api.machinemail.dev/v0/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m/verify" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

## [Get Zone File](/content/docs/reference/api/domains\#get-zone-file/index.html)

http

```
GET /v0/domains/{domain_id}/zone-file
```

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_read`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-5/index.html)

FieldDescription

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-7/index.html)

**200** A BIND zone file with the records to publish (`text/plain`)

Headers:

FieldDescription

`Content-Disposition``string`

attachment; filename="<domain>.zone"

#### [Errors](/content/docs/reference/api/domains\#errors-7/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-7/index.html)

Request

```
curl "https://api.machinemail.dev/v0/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m/zone-file" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

## [List Domains in Pod](/content/docs/reference/api/domains\#list-domains-in-pod/index.html)

http

```
GET /v0/pods/{pod_id}/domains
```

Same as List Domains (`GET /v0/domains`), limited to the pod.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_read`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-6/index.html)

FieldDescription

`pod_id``string`Required

ID of the pod.

#### [Query parameters](/content/docs/reference/api/domains\#query-parameters-1/index.html)

FieldDescription

`limit``integer`

Maximum number of items to return. Default 50, maximum 500; larger values are capped.

`page_token``string`

next\_page\_token from the previous page.

`ascending``boolean`

Sort oldest first.

#### [Response](/content/docs/reference/api/domains\#response-8/index.html)

**200** A page of domains (`application/json`)

FieldDescription

`count``integer`Required

Number of items returned.

`limit``integer`

Maximum number of items per page. Default 50, maximum 500; larger values are capped.

`next_page_token``string`

Page token for pagination. Absent on the last page.

`domains` [DomainItem\[\]](/content/docs/reference/api/objects#domainitem/index.html) Required

Ordered by created\_at, newest first unless ascending is set.

Each item of `domains` is a [DomainItem](/content/docs/reference/api/objects#domainitem/index.html):

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

Verification status, as on Domain.

`reason``string`

Why the domain is not verified yet, as on Domain.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish, as on Domain.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

#### [Errors](/content/docs/reference/api/domains\#errors-8/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-8/index.html)

Request

```
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/domains" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

## [Create Domain in Pod](/content/docs/reference/api/domains\#create-domain-in-pod/index.html)

http

```
POST /v0/pods/{pod_id}/domains
```

Same as Create Domain (`POST /v0/domains`), limited to the pod.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_create`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-7/index.html)

FieldDescription

`pod_id``string`Required

ID of the pod.

#### [Request body](/content/docs/reference/api/domains\#request-body-2/index.html)

Content type: `application/json`.

FieldDescription

`domain``string`Required

The domain name, for example example.com. Cannot be the shared domain or a domain another organization registered.

`feedback_enabled``boolean`

Stored and returned; has no effect. Default false.

`inbound_enabled``boolean`

Receive email for this domain. Default true. false makes it send-only (the inbound MX record is not required).

`client_id``string`

`pod_id``string`

Pod to create the domain in. Defaults to the credential pod or the organization default pod. A pod-scoped credential can only name its own pod.

`catch_all``boolean`

Create an inbox for any address at the domain that receives mail. Default false.

`catch_all_ttl_seconds``integer | null`

Make inboxes created by catch-all ephemeral with this TTL. null or absent: permanent.

#### [Response](/content/docs/reference/api/domains\#response-9/index.html)

**200** A domain with this client\_id already exists; it is returned unchanged. (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

**201** Created (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

#### [Errors](/content/docs/reference/api/domains\#errors-9/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-9/index.html)

Request

```
curl -X POST "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/domains" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "domain": "example.com",
  "feedback_enabled": false
}'
```

Response 200

## [Get Domain in Pod](/content/docs/reference/api/domains\#get-domain-in-pod/index.html)

http

```
GET /v0/pods/{pod_id}/domains/{domain_id}
```

Same as Get Domain (`GET /v0/domains/{domain_id}`), limited to the pod.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_read`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-8/index.html)

FieldDescription

`pod_id``string`Required

ID of the pod.

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-10/index.html)

**200** The domain (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

#### [Errors](/content/docs/reference/api/domains\#errors-10/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-10/index.html)

Request

```
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

## [Update Domain in Pod](/content/docs/reference/api/domains\#update-domain-in-pod/index.html)

http

```
PATCH /v0/pods/{pod_id}/domains/{domain_id}
```

Same as Update Domain (`PATCH /v0/domains/{domain_id}`), limited to the pod.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_update`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-9/index.html)

FieldDescription

`pod_id``string`Required

ID of the pod.

`domain_id``string`Required

ID of the domain.

#### [Request body](/content/docs/reference/api/domains\#request-body-3/index.html)

Content type: `application/json`.

FieldDescription

`feedback_enabled``boolean`

Stored and returned; has no effect.

`inbound_enabled``boolean`

Receive email for this domain. false makes the inbound MX record optional and re-evaluates the status.

`catch_all``boolean`

Create an inbox for any address at the domain that receives mail.

`catch_all_ttl_seconds``integer | null`

TTL of inboxes created by catch-all from now on. null makes them permanent.

#### [Response](/content/docs/reference/api/domains\#response-11/index.html)

**200** The updated domain (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

#### [Errors](/content/docs/reference/api/domains\#errors-11/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-11/index.html)

Request

```
curl -X PATCH "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
  "feedback_enabled": false
}'
```

Response 200

## [Delete Domain in Pod](/content/docs/reference/api/domains\#delete-domain-in-pod/index.html)

http

```
DELETE /v0/pods/{pod_id}/domains/{domain_id}
```

Same as Delete Domain (`DELETE /v0/domains/{domain_id}`), limited to the pod.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_delete`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-10/index.html)

FieldDescription

`pod_id``string`Required

ID of the pod.

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-12/index.html)

**200** Deleted (`application/json`)

FieldDescription

`ok``true`Required

#### [Errors](/content/docs/reference/api/domains\#errors-12/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-12/index.html)

Request

```
curl -X DELETE "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

```
{
  "ok": true
}
```

## [Get Domain Connect Setup in Pod](/content/docs/reference/api/domains\#get-domain-connect-setup-in-pod/index.html)

http

```
GET /v0/pods/{pod_id}/domains/{domain_id}/domain-connect
```

Same as Get Domain Connect Setup (`GET /v0/domains/{domain_id}/domain-connect`), limited to the pod.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_read`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-11/index.html)

FieldDescription

`pod_id``string`Required

ID of the pod.

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-13/index.html)

**200** Domain Connect support for the domain (`application/json`)

FieldDescription

`supported``boolean`Required

The zone DNS provider supports Domain Connect and has the MachineMail template.

`provider_name``string`

Display name of the DNS provider.

`apply_url``string`

Signed link that opens the provider with the outstanding records prefilled. Absent when nothing is left to add.

`provider_id``string`

Domain Connect provider ID.

`url_sync_ux``string`

Base URL of the provider synchronous flow.

`width``integer`

Suggested popup width, in pixels.

`height``integer`

Suggested popup height, in pixels.

Why one-click setup is not available, or already\_configured when nothing is left to add.

`checked_at``string (date-time)`Required

When discovery last ran.

#### [Errors](/content/docs/reference/api/domains\#errors-13/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-13/index.html)

Request

```
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m/domain-connect" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

## [Verify Domain in Pod](/content/docs/reference/api/domains\#verify-domain-in-pod/index.html)

http

```
POST /v0/pods/{pod_id}/domains/{domain_id}/verify
```

Same as Verify Domain (`POST /v0/domains/{domain_id}/verify`), limited to the pod.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_update`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-12/index.html)

FieldDescription

`pod_id``string`Required

ID of the pod.

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-14/index.html)

**200** The domain after the check (`application/json`)

FieldDescription

`pod_id``string`Required

ID of the pod the domain belongs to.

`domain_id``string`Required

ID of the domain.

`domain``string`Required

The domain name (for example example.com), lowercased.

`feedback_enabled``boolean`Required

Stored as given. MachineMail does not send bounce and complaint notifications to inboxes; use the message.bounced and message.complained events.

`inbound_enabled``boolean`Required

Receive email for this domain. false makes it send-only: the inbound MX record is not required.

`subdomains_enabled``boolean`Required

Always false: inboxes on subdomains are not supported.

`tracking_enabled``boolean`Required

Always false: open tracking is not supported.

`client_id``string`

Client ID given at creation (idempotency key).

`updated_at``string (date-time)`Required

Time at which the domain was last updated.

`created_at``string (date-time)`Required

Time at which the domain was created.

`status``"NOT_STARTED" | "PENDING" | "INVALID" | "FAILED" | "VERIFYING" | "VERIFIED"`Required

`reason``string`

Why the domain is not verified yet: what to do next, or which records are missing or invalid. Absent once VERIFIED.

`records` [VerificationRecord\[\]](/content/docs/reference/api/objects#verificationrecord/index.html) Required

DNS records to publish.

`organization_id``string`Required

ID of the organization.

`catch_all``boolean`Required

Mail to any address at the domain without an inbox creates one (created\_by: catch\_all).

`catch_all_ttl_seconds``integer`

TTL of inboxes created by catch-all; absent means they are permanent.

`nameservers``string[]`

Authoritative nameservers, detected on create and verify.

`dns_provider``"cloudflare" | "route53" | "google" | "vercel" | "namecheap" | "godaddy" | "digitalocean" | "hetzner" | "porkbun" | "other"`

DNS host the nameservers belong to.

`dns_provider_url``string`

Link to the DNS host console.

`domain_connect``object`

One-click DNS setup (Domain Connect), from the last discovery. See Get Domain Connect Setup.

`verified_at``string (date-time)`

When the domain became VERIFIED.

`last_checked_at``string (date-time)`

When the DNS records were last checked.

Each item of `records` is a [VerificationRecord](/content/docs/reference/api/objects#verificationrecord/index.html):

FieldDescription

`type``"TXT" | "CNAME" | "MX"`Required

`name``string`Required

Name (host) of the record.

`value``string`Required

Value of the record.

`status``"MISSING" | "INVALID" | "VALID"`Required

MISSING: not published yet. INVALID: published with the wrong value.

`priority``integer`

Priority of an MX record.

`reason``string`

Why an INVALID record is invalid: Found: <values seen>.

`purpose``"inbound" | "spf" | "dkim" | "dmarc" | "provider"`Required

What the record is for. provider records come from the sending provider.

`required``boolean`Required

Whether the record must be valid for the domain to verify. The inbound MX record is not required when inbound\_enabled is false.

#### [Errors](/content/docs/reference/api/domains\#errors-14/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-14/index.html)

Request

```
curl -X POST "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m/verify" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

Response 200

## [Get Zone File in Pod](/content/docs/reference/api/domains\#get-zone-file-in-pod/index.html)

http

```
GET /v0/pods/{pod_id}/domains/{domain_id}/zone-file
```

Same as Get Zone File (`GET /v0/domains/{domain_id}/zone-file`), limited to the pod.

**Authentication:**`Authorization: Bearer <api key>` or the dashboard `mm_session` cookie. Permission: `domain_read`.

#### [Path parameters](/content/docs/reference/api/domains\#path-parameters-13/index.html)

FieldDescription

`pod_id``string`Required

ID of the pod.

`domain_id``string`Required

ID of the domain.

#### [Response](/content/docs/reference/api/domains\#response-15/index.html)

**200** A BIND zone file with the records to publish (`text/plain`)

Headers:

FieldDescription

`Content-Disposition``string`

attachment; filename="<domain>.zone"

#### [Errors](/content/docs/reference/api/domains\#errors-15/index.html)

Error bodies use the [error envelope](/content/docs/reference/errors/index.html).

#### [Example](/content/docs/reference/api/domains\#example-15/index.html)

Request

```
curl "https://api.machinemail.dev/v0/pods/pod_01k6x2m9qd0001b8j4mr0w3d5f/domains/dom_01k6x3d5kq0000g3q9sx5b8j0m/zone-file" \
  -H "Authorization: Bearer $MACHINEMAIL_API_KEY"
```

On this page

[List Domains](/content/docs/reference/api/domains#list-domains/index.html) [Create Domain](/content/docs/reference/api/domains#create-domain/index.html) [Get Domain](/content/docs/reference/api/domains#get-domain/index.html) [Update Domain](/content/docs/reference/api/domains#update-domain/index.html) [Delete Domain](/content/docs/reference/api/domains#delete-domain/index.html) [Get Domain Connect Setup](/content/docs/reference/api/domains#get-domain-connect-setup/index.html) [Verify Domain](/content/docs/reference/api/domains#verify-domain/index.html) [Get Zone File](/content/docs/reference/api/domains#get-zone-file/index.html) [List Domains in Pod](/content/docs/reference/api/domains#list-domains-in-pod/index.html) [Create Domain in Pod](/content/docs/reference/api/domains#create-domain-in-pod/index.html) [Get Domain in Pod](/content/docs/reference/api/domains#get-domain-in-pod/index.html) [Update Domain in Pod](/content/docs/reference/api/domains#update-domain-in-pod/index.html) [Delete Domain in Pod](/content/docs/reference/api/domains#delete-domain-in-pod/index.html) [Get Domain Connect Setup in Pod](/content/docs/reference/api/domains#get-domain-connect-setup-in-pod/index.html) [Verify Domain in Pod](/content/docs/reference/api/domains#verify-domain-in-pod/index.html) [Get Zone File in Pod](/content/docs/reference/api/domains#get-zone-file-in-pod/index.html)

100% readTop
