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

# Verify a custom domain

`POST /websites/{websiteId}/domains/{domainId}/verify`

## Request

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

Re-checks the ownership TXT record, edge readiness, and whether an HTTPS request to the hostname reaches this Cactal domain, then returns the updated status. A customer CDN or reverse proxy in front is supported when it forwards the verification request to Cactal. `failureMessage` distinguishes a missing ownership record, an unreachable hostname, and a hostname served somewhere else. Cactal asks the domain nameservers directly, so new records usually count on the next check, and this endpoint is safe to poll; Cactal also re-checks pending domains automatically (every minute for the first 2 hours, every 5 minutes for the first day, then every 15 minutes). The first custom domain to become active is promoted to primary automatically.

## Path parameters

- `websiteId` string, required
- `domainId` string, required

## Response `200`

The domain with its freshly checked status. When not yet `active`, `failureMessage` explains whether ownership, reachability, routing, or edge readiness needs attention.

- 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)
