---
title: "Add a custom domain"
method: POST
path: "/websites/{websiteId}/domains"
tags: ["Domains"]
---

# Add a custom domain

`POST /websites/{websiteId}/domains`

## Request

- Base URL: `https://api.cactal.ai/v1`
- URL: `https://api.cactal.ai/v1/websites/{websiteId}/domains`
- Auth: HTTP bearer

Claims `hostname` for this website and registers it with the Cactal edge. Custom domains must first be enabled for the website (`websiteDomains.setEnabled`, owner-only — enabling is the billing moment); the request fails with 403 `custom_domains_disabled` otherwise. Adding or removing domains on an enabled website never changes billing. The domain is created in `pending_dns` status, and the returned `dnsRecords` list exactly what to create at your DNS provider: an ownership TXT record on `_cactal.<hostname>` plus a routing record (a CNAME for subdomains or an A record for apex domains). Hostnames must be lowercase ASCII domains (not IP addresses or Cactal platform hosts), each website can have at most 10 custom domains, and a hostname can be claimed by only one website; claims that never verify expire after 7 days. After creating the records, call the verify endpoint or wait for the automatic re-checks.

## Path parameters

- `websiteId` string, required

## Request body

- object
  - `hostname` string, required

## Response `200`

The created domain in `pending_dns` status. Next: create the `dnsRecords` at your DNS provider, then call `websiteDomains.verifyCustomDomain`.

- object
  - `id` string, required: Unique domain id.
  - `hostname` string, required: Fully-qualified lowercase hostname, e.g. `blog.example.com`.
  - `status` 'pending_dns' | 'pending_verification' | 'active' | 'failed' | 'removing' | 'suspended', required: `pending_dns`: waiting for the required DNS records; `pending_verification`: DNS found, waiting for the edge host to become ready; `active`: serving traffic; `failed`: verification failed (see `failureMessage`); `removing`: being deregistered from the edge; `suspended`: disabled by Cactal trust & safety. Platform subdomains are always `active`.
  - `kind` 'platform_subdomain' | 'custom', required: Every website automatically gets one `platform_subdomain`; `custom` domains are added through this API.
  - `isPrimary` boolean, required: Whether this is the canonical custom domain that published traffic redirects to. Always `false` for platform subdomains.
  - `dnsRecords` object[], required: DNS records the domain owner must create for verification to succeed. Empty for platform subdomains.
    - `type` 'TXT' | 'CNAME' | 'A', required: DNS record type to create.
    - `name` string, required: Fully-qualified name (host) to create the record on.
    - `value` string, required: Exact value the record must resolve to.
    - `purpose` 'ownership' | 'routing', required: `ownership` records prove control of the hostname (TXT); `routing` records point traffic at the Cactal edge (CNAME for subdomains, A for apex domains).
  - `failureMessage` string, nullable, required: What the most recent verification check found wrong, including whether ownership is missing, the hostname is unreachable, or traffic reaches a service other than Cactal. `null` when nothing is wrong.
  - `lastCheckedAt` string, date-time, nullable, required: When DNS and edge status were last checked. `null` before the first check.
  - `createdAt` string, date-time, required: When the domain record was created.

## Other responses

- `400`: Validation failed. The response `message` names the first invalid field.
- `401`: Missing, invalid, expired, or revoked API key.
- `403`: The authenticated principal lacks the required capability.
- `404`: The resource does not exist or is outside the principal’s access scope.
- `409`: The request conflicts with the current state of the resource.
- `429`: Rate limit exceeded. Retry after the number of seconds in the `Retry-After` header.

---

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