> ## Documentation Index
> Fetch the complete documentation index at: https://docs.drin.run/llms.txt
> Use this file to discover all available pages before exploring further.

# Add a domain

> POST /v1/domains — register a sending domain and get back the DKIM, SPF, and DMARC records to publish.

Register a domain you own so you can send from your own brand. The response carries the exact DNS records to publish; once they resolve, call verify.

**`POST /v1/domains`**

Creating a domain returns it in `pending` status along with a `records` array — DKIM (a `CNAME`), SPF, and DMARC (both `TXT`). Publish all of them at your DNS provider, then [verify](/api-reference/domains/verify) to flip the domain to `verified`.

## Body

<ParamField body="domain" type="string" required>
  The fully-qualified domain or subdomain to send from, for example `mail.acme.com`. A subdomain dedicated to sending is recommended so DMARC policy on your root domain is untouched.
</ParamField>

Account-wide keys may name the owning project with the `X-Drin-Product` header; project-scoped keys omit it. See [Authentication](/authentication).

## Request

<CodeGroup>
  ```bash cURL theme={null}
  curl https://api.drin.run/v1/domains \
    -H "Authorization: Bearer $DRIN_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{ "domain": "mail.acme.com" }'
  ```

  ```typescript Node.js theme={null}
  import { DrinClient } from "@drin00/sdk";

  const drin = new DrinClient({ apiKey: process.env.DRIN_API_KEY });

  const domain = await drin.domains.create({ domain: "mail.acme.com" });

  // Publish each record at your DNS provider, then call verify.
  for (const record of domain.records) {
    console.log(record.type, record.name, record.value);
  }
  ```

  ```python Python theme={null}
  import os, requests

  r = requests.post(
      "https://api.drin.run/v1/domains",
      headers={"Authorization": f"Bearer {os.environ['DRIN_API_KEY']}"},
      json={"domain": "mail.acme.com"},
  )
  print(r.json())
  ```
</CodeGroup>

## Response

`201 Created` — the domain plus the records to publish. Each record carries a `purpose` (`dkim`, `spf`, `dmarc`) and a `verified` flag that stays `false` until the record resolves.

```json theme={null}
{
  "id": "dom_01HZ8K3M9P",
  "domain": "mail.acme.com",
  "status": "pending",
  "records": [
    {
      "type": "CNAME",
      "name": "abcd1234._domainkey.mail.acme.com",
      "value": "abcd1234.dkim.drin.run",
      "purpose": "dkim",
      "verified": false
    },
    {
      "type": "TXT",
      "name": "mail.acme.com",
      "value": "v=spf1 include:drin.run ~all",
      "purpose": "spf",
      "verified": false
    },
    {
      "type": "TXT",
      "name": "_dmarc.mail.acme.com",
      "value": "v=DMARC1; p=none;",
      "purpose": "dmarc",
      "verified": false
    }
  ]
}
```

<Note>
  **No DNS yet?** You can send from a shared onboarding domain in test mode without adding a domain at all — it just can only deliver to your own address. See the [Quickstart](/quickstart).
</Note>
