
# Custom domain

A custom domain for an application on a server: the application responds not only at the address issued by the platform, but also at a name you own. Attaching takes two steps — you receive DNS records, create them at your DNS provider, and run verification. The platform issues the `https` certificate itself after verification.

Scope: `vibe:infra`

## Operations

- [Attach a domain](./domain/attach.md) — `POST /v1/infra/servers/:id/domain`
- [Get the domain](./domain/get.md) — `GET /v1/infra/servers/:id/domain`
- [Verify the domain](./domain/verify.md) — `POST /v1/infra/servers/:id/domain/verify`
- [Detach the domain](./domain/detach.md) — `DELETE /v1/infra/servers/:id/domain`

## Access

Only the key that manages the server can run these operations. Any other key, including a second key of the same owner, receives `404 SERVER_NOT_FOUND`. The server identifier is the `id` field from the [server list](/docs/infra/servers/list).

Attaching, verifying and detaching require the `vibe:infra` scope. Reading the state requires no scope.

Attaching and verifying are available under three conditions, and each one has its own `403` refusal code:

| Condition | Refusal code |
|---------|------------|
| Custom domains are enabled for the server owner | `CUSTOM_DOMAINS_DISABLED` |
| The region of the Bitrix24 account supports custom domains | `CUSTOM_DOMAINS_ZONE_UNSUPPORTED` |
| The Bitrix24 account is on a commercial plan | `CUSTOM_DOMAINS_REQUIRE_COMMERCIAL` |

Reading and detaching do not check these conditions: an attached domain can always be read and detached.

## DNS records

The attach and read responses carry an `instructions` array of two records:

| Record | Purpose |
|--------|------------|
| `TXT` | Confirms that the domain is yours. The value is `vibe-verify=…`, unique to each attachment |
| `CNAME` or `A` | Points the domain at the platform. A subdomain (`app.example.com`) gets a `CNAME`, a root domain (`example.com`) gets an `A` |

Each record has two names. `host` is the full record name. `name` is the same name relative to `zone`: this is what the "name" field in the DNS provider's panel expects, and for the zone itself it is `@`. If you enter the full name in the panel, the provider appends the zone once more, and verification does not find that record.

The domain name must not have an `AAAA` record: the platform accepts requests over IPv4 only.

## Domain statuses

| Status | Meaning |
|--------|--------------|
| `PENDING_VERIFICATION` | The domain is attached, verification has not been run yet |
| `VERIFYING` | Verification is in progress |
| `ACTIVE` | The records are correct, the application responds at the domain |
| `FAILED` | The last verification did not find the required records |
| `SUSPENDED` | The domain was working but has been disabled: the records no longer point at the platform, the Bitrix24 account is deactivated, or detaching did not complete |

A domain in the `FAILED` or `SUSPENDED` status returns to `ACTIVE` through the same [verification](./domain/verify.md) once the records are fixed.

## Typical scenario

1. [`POST /domain`](./domain/attach.md) with the domain name — the response contains the `instructions` records.
2. Create both records at the DNS provider, putting `name` into the "name" field.
3. [`POST /domain/verify`](./domain/verify.md). A `200` response means the domain is in the `ACTIVE` status. A `422` response means `error.details.records` names the record that is missing or incorrect. Retrying verification immediately is pointless: DNS changes take time to propagate, so wait a few minutes.
4. [`GET /domain`](./domain/get.md) until `certIssued` becomes `true` — from that moment the domain opens over `https`.

## See also

- [Infrastructure](/docs/infra)
- [Servers](/docs/infra/servers)
- [Full application deploy](/docs/infra/deploy/deploy)
- [Changelog](/docs/changelog)
