---
title: "Add a sending domain"
method: POST
path: "/domains"
tags: ["Domains"]
---

# Add a sending domain

`POST /domains`

## Request

- Base URL: `https://api.groundmail.dev`
- URL: `https://api.groundmail.dev/domains`
- Auth: HTTP bearer

## Request body

- CreateDomainRequest
  - `name` string, required
  - `inbound_enabled` boolean: Request inbound receiving for the domain as soon as verification succeeds.
  - `inboundEnabled` boolean: Alias for inbound_enabled.
  - `tenant` string: Give the new domain to this tenant (its `external_id` or `id`). Only that tenant can send from it. A key limited to one tenant always adds domains to its tenant.

## Response `200`

Domain created with DNS records to add

- CreateDomainResponse
  - `domain` Domain, required
    - `id` string, required
    - `name` string, required
    - `status` 'pending' | 'verified' | 'failed', required
    - `created_at` string, date-time, required
    - `verified_at` string, date-time, nullable, required
    - `open_tracking` boolean, required: Open tracking preference for this domain.
    - `click_tracking` boolean, required: Click tracking preference for this domain.
    - `tracking_status` 'disabled' | 'pending' | 'active' | 'error', required: Whether open/click tracking is applied to outgoing mail. `disabled` when both preferences are off, `pending` until the tracking CNAME is accepted and a certificate is issued for the tracking hostname (links and opens are not tracked yet; this takes a few minutes after the CNAME is added), `active` once both are done, `error` when tracking or the certificate could not be set up. Re-checked when you verify the domain and when you read it.
    - `tracking_error` string, nullable, required: Why tracking is not active yet, when `tracking_status` is `pending` or `error`.
    - `tls_mode` 'opportunistic' | 'enforced', required: Preferred outbound TLS behavior for this domain.
    - `inbound_enabled` boolean, required: True when Groundmail should accept inbound mail for this domain.
    - `inbound_status` 'disabled' | 'pending' | 'active' | 'error', required: `pending` before verification, `active` once inbound receiving is configured, or `error` when setup fails.
    - `inbound_error` string, nullable, required: Last inbound configuration error, if any.
    - `inbound_spam_threshold` number, nullable: Received mail scoring at or above this is `spam` (and dropped when `inbound_spam_action` is `drop`). Null uses the default (10) and drops nothing.
    - `inbound_spam_action` 'flag' | 'drop': `flag` keeps spam with `spam_status: spam`; `drop` discards it (no stored email, no webhook).
    - `tenant` string: The `external_id` of the tenant that owns this domain. Present only on a tenant's domain.
  - `records` DnsRecord[], required
    - `type` string, required: DNS record type (`TXT`, `CNAME`, or `MX`)
    - `host` string, required
    - `value` string, required: Record content. For MX records, the mail server hostname (priority is in `priority`).
    - `priority` integer: MX preference when `type` is `MX` (lower is preferred).
    - `purpose` string, required: Human-readable purpose (`Domain ownership`, `DKIM`, `Return path`, `SPF`, `DMARC`, `Inbound receiving`)
  - `inbound_records` DnsRecord[], required
    - `type` string, required: DNS record type (`TXT`, `CNAME`, or `MX`)
    - `host` string, required
    - `value` string, required: Record content. For MX records, the mail server hostname (priority is in `priority`).
    - `priority` integer: MX preference when `type` is `MX` (lower is preferred).
    - `purpose` string, required: Human-readable purpose (`Domain ownership`, `DKIM`, `Return path`, `SPF`, `DMARC`, `Inbound receiving`)
  - `inbound_note` string, required
  - `mail_server_dns_synced` boolean: Whether mail-server DKIM/return-path records were synced into the response records
  - `mail_server_dns_error` string: Present when mail-server DNS sync failed; ownership/SPF/DMARC records are still returned

## Other responses

- `400`: Invalid domain
- `401`: Unauthorized
- `403`: Plan domain limit reached (when billing is enabled), or `tenant` named on an account without tenants (`tenants_not_enabled`)
- `409`: Domain already added on this team, or already owned by another team

---

[API](https://skmtc.dev/groundmail/apis/groundmail-api.md) · [All operations](https://skmtc.dev/groundmail/apis/groundmail-api/llms.txt) · [OpenAPI document](https://skmtc.dev/groundmail/apis/groundmail-api/revisions/479821c9fecf?raw)
