# Domains (/api/domains)

All endpoints require `Authorization: Bearer ck_...`.

## List domains [#list-domains]

`GET /v1/domains`

**Scope:** `domains:list`

### Query parameters [#query-parameters]

| Parameter | Type | Default | Description |
|-----------|------|---------|-------------|
| `page` | integer | `1` | Page number (min 1) |
| `limit` | integer | `100` | One of `1`, `5`, `10`, `25`, `50`, `100` |
| `verified` | boolean | — | Filter by verification status |
| `name` | string | — | Max 128 chars |

### Response `200` [#response-200]

```json
{
  "count": 0,
  "data": []
}
```

Each item in `data` is a [Domain](/reference/schemas#domain).

---

## Create domain [#create-domain]

`POST /v1/domains`

**Scope:** `domains:create`

Register a domain. **Subdomain required** (e.g. `track.example.com`).

<Callout type="warn">

Rejected if `name` contains `http`, `www`, or `/`, or is not a valid subdomain hostname.

</Callout>

### Request body [#request-body]

```json
{
  "name": "track.example.com"
}
```

| Field | Type | Required | Description |
|-------|------|----------|-------------|
| `name` | string | yes | Subdomain hostname — no scheme, `www`, or path. Max 128 chars. |

### Response `201` [#response-201]

```json
{
  "id": 1,
  "name": "track.example.com",
  "verified": false,
  "migrated": false
}
```

---

## Verify domain [#verify-domain]

`PATCH /v1/domains/:id/verify`

**Scope:** `domains:verify`

Checks DNS/CNAME propagation and activates the certificate. No request body.

**Rate limit:** 1 request per domain ID per 30 seconds (in addition to the global API key limit). Faster polling returns `429` and does not speed up verification.

### Path parameters [#path-parameters]

| Name | Type | Description |
|------|------|-------------|
| `id` | integer | Domain ID |

### Response `200` [#response-200-1]

```json
{
  "name": "track.example.com",
  "verified": true
}
```

### Polling for verification [#polling-for-verification]

DNS/CNAME propagation and certificate activation can take several minutes. Poll until `verified: true` before using the domain in campaigns.

<Callout type="warn">

Do not spam verify requests. Each call checks upstream infrastructure (Cloudflare). The API allows **one verify per domain ID every 30 seconds** — retrying faster returns `429` and does not help.

Wait at least **30 seconds** between attempts on the same domain ID. A practical interval is **30–60 seconds**.

</Callout>

---

## Delete domain [#delete-domain]

`DELETE /v1/domains/:id`

**Scope:** `domains:delete`

### Response `204` [#response-204]

Same quirk as campaign delete — status `204`, optional `{ "message": "..." }` body. Treat status as success.
