## Привязать домен

`POST /v1/infra/servers/:id/domain`

Закрепляет ваше доменное имя за приложением на сервере и открывает первый шаг привязки — создание DNS-записей у DNS-провайдера домена. Запросы по домену приложение начинает принимать только после успешной проверки записей. У одного сервера один домен.

Кому доступен вызов — [Доступ](/docs/infra/domain#доступ). Назначение записей и разница между именами `host` и `name` — [DNS-записи](/docs/infra/domain#dns-записи).

## Параметры

| Параметр | В | Тип | Обяз. | Описание |
|----------|---|-----|:-----:|----------|
| `id` | path | string (UUID) | да | ID сервера. Источник — поле `id` из [списка серверов](/docs/infra/servers/list) |

## Поля запроса (body)

| Поле | Тип | Обяз. | Описание |
|------|-----|:-----:|----------|
| `fqdn` | string | да | Доменное имя без схемы, порта и пути, например `app.example.com`. Принимается поддомен или корневой домен. Регистр не учитывается, пробелы по краям отбрасываются. Имя состоит минимум из двух меток через точку, каждая метка — от 1 до 63 латинских букв, цифр и дефисов, дефис не стоит в начале и в конце метки |

## Примеры

### curl — личный ключ

```bash
curl -X POST "https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/domain" \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "fqdn": "app.example.com"
  }'
```

### curl — OAuth-приложение

```bash
curl -X POST "https://vibecode.bitrix24.tech/v1/infra/servers/SERVER_ID/domain" \
  -H "X-Api-Key: YOUR_APP_KEY" \
  -H "Authorization: Bearer USER_SESSION_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{
    "fqdn": "app.example.com"
  }'
```

### JavaScript — личный ключ

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/domain`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_API_KEY',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      fqdn: 'app.example.com',
    }),
  }
)
const { data } = await res.json()
for (const record of data.instructions) {
  console.log(`${record.type} ${record.name} → ${record.value}`)
}
```

### JavaScript — OAuth-приложение

```javascript
const res = await fetch(
  `https://vibecode.bitrix24.tech/v1/infra/servers/${serverId}/domain`,
  {
    method: 'POST',
    headers: {
      'X-Api-Key': 'YOUR_APP_KEY',
      'Authorization': 'Bearer USER_SESSION_TOKEN',
      'Content-Type': 'application/json',
    },
    body: JSON.stringify({
      fqdn: 'app.example.com',
    }),
  }
)
```

## Поля ответа

| Поле | Тип | Описание |
|------|-----|----------|
| `success` | boolean | Всегда `true` при успехе |
| `data.domain.id` | string (UUID) | ID привязки домена |
| `data.domain.fqdn` | string | Привязанное имя в нижнем регистре |
| `data.domain.isApex` | boolean | `true` — корневой домен зоны, `false` — поддомен |
| `data.domain.status` | string | Статус домена. После привязки — `"PENDING_VERIFICATION"`. Все значения — [Статусы домена](/docs/infra/domain#статусы-домена) |
| `data.domain.source` | string | Происхождение домена. `"BYO"` — домен ваш и подключён вами |
| `data.domain.dnsMode` | string | Кто ведёт DNS-записи. `"USER_DNS"` — вы, у своего DNS-провайдера |
| `data.domain.verifiedAt` | string (ISO 8601) \| null | Момент успешной проверки, после которой домен стал `ACTIVE`. После привязки — `null` |
| `data.domain.lastVerifiedAt` | string (ISO 8601) \| null | Момент последней проверки записей, включая неуспешную. После привязки — `null` |
| `data.domain.createdAt` | string (ISO 8601) | Момент привязки |
| `data.domain.certIssued` | boolean | Выпущен ли сертификат для `https`. После привязки — `false` |
| `data.instructions` | array | Две DNS-записи, которые нужно создать у DNS-провайдера домена |
| `data.instructions[].type` | string | Тип записи: `"TXT"`, `"CNAME"` или `"A"` |
| `data.instructions[].host` | string | Полное имя записи |
| `data.instructions[].zone` | string | Зона, в которой создаётся запись |
| `data.instructions[].name` | string | Имя записи относительно `zone` — его вводят в поле «имя» панели DNS-провайдера. Для самой зоны — `"@"` |
| `data.instructions[].value` | string | Значение записи |

## Пример ответа

Ответ `201` на привязку поддомена:

```json
{
  "success": true,
  "data": {
    "domain": {
      "id": "bea9db66-411b-432e-a365-283a74f5714f",
      "fqdn": "app.example.com",
      "isApex": false,
      "status": "PENDING_VERIFICATION",
      "source": "BYO",
      "dnsMode": "USER_DNS",
      "verifiedAt": null,
      "lastVerifiedAt": null,
      "createdAt": "2026-10-05T12:53:02.616Z",
      "certIssued": false
    },
    "instructions": [
      {
        "type": "TXT",
        "host": "_vibecode-challenge.app.example.com",
        "zone": "example.com",
        "name": "_vibecode-challenge.app",
        "value": "vibe-verify=f36ac31f213d1e3630c75f000b6631f5"
      },
      {
        "type": "CNAME",
        "host": "app.example.com",
        "zone": "example.com",
        "name": "app",
        "value": "lb.bitrix24site.ru"
      }
    ]
  }
}
```

Корневой домен `example.com` получил бы `"isApex": true`, а второй записью — `"type": "A"` с `"name": "@"` и IPv4-адресом в `value`. Остальная форма ответа не меняется.

## Пример ответа при ошибке

409 — имя уже привязано к другому серверу платформы:

```json
{
  "success": false,
  "error": {
    "code": "DOMAIN_TAKEN",
    "message": "This domain is already in use"
  }
}
```

## Ошибки

| HTTP | Код | Описание |
|------|-----|----------|
| 400 | `INVALID_REQUEST` | Поле `fqdn` не передано или не является доменным именем |
| 400 | `FQDN_INVALID` | В `fqdn` передан IP-адрес |
| 400 | `FQDN_RESERVED` | Имя принадлежит платформе: это её домен или его поддомен |
| 400 | `FQDN_FORBIDDEN` | Имя запрещено: в нём есть подстрока `bitrix` |
| 400 | `INVALID_JSON_BODY` | Тело запроса не разбирается как JSON |
| 409 | `CUSTOM_DOMAIN_GALAXY_MOVE_ACTIVE` | Сервер переезжает в Галактику: это старый сервер переезда или подготовленное для него место. Привяжите домен после того, как переезд завершится или будет отменён |
| 409 | `CUSTOM_DOMAIN_LIMIT` | У сервера уже есть домен, в том числе с тем же именем. Сначала [отвяжите его](./detach.md) |
| 409 | `DOMAIN_TAKEN` | Имя привязано к другому серверу платформы |
| 409 | `DOMAIN_TAKEN_EXTERNAL` | Имя подключено к другому продукту Битрикс24. Отключите его там и повторите вызов |
| 503 | `CUSTOM_DOMAIN_REGISTRY_UNAVAILABLE` | Реестр доменов не ответил. Домен не привязан, повторите вызов позже |
| 403 | `CUSTOM_DOMAINS_DISABLED` | Свои домены не включены для владельца сервера |
| 403 | `CUSTOM_DOMAINS_ZONE_UNSUPPORTED` | Регион аккаунта Битрикс24 не поддерживает свои домены |
| 403 | `CUSTOM_DOMAINS_REQUIRE_COMMERCIAL` | У аккаунта Битрикс24 нет коммерческого тарифа |
| 401 | `MISSING_API_KEY` | Не передан заголовок `X-Api-Key` |
| 401 | `INVALID_API_KEY` | Ключ не опознан: такой строки на платформе нет |
| 403 | `INFRA_SCOPE_REQUIRED` | У ключа нет скоупа `vibe:infra` |
| 403 | `INFRA_FORBIDDEN_FOR_COWORK_KEY` | Вызов сделан ключом Cowork/Code — такой ключ работает только с данными, изменяющие операции ему закрыты. Что делать — [Проектный ключ для деплоя](/docs/cowork/deploy-key) |
| 403 | `WRITE_BLOCKED_READONLY_KEY` | Ключ в режиме «только чтение» — изменяющие операции ему закрыты |
| 404 | `SERVER_NOT_FOUND` | Сервера с таким `id` нет, либо им управляет не тот ключ, которым сделан вызов |
| 429 | `RATE_LIMITED` | Превышен лимит 5 запросов в минуту на этот эндпоинт. Лимит считается на владельца ключа, а не на отдельный ключ. Точное значение — в заголовке `x-ratelimit-limit` (потолок делится на реплики) |
| 503 | `user_self_deletion_pending` | Владелец ключа запросил удаление своего аккаунта на портале. Доступ вернётся после отмены удаления |

Полный список общих ошибок API — [Ошибки](/docs/errors).

## Известные особенности

- **Порядок проверок.** Скоуп ключа и принадлежность сервера проверяются первыми, затем три условия доступа к своим доменам, и только после них — тело запроса. Поэтому запрос с некорректным `fqdn` от аккаунта, которому свои домены недоступны, получит `403`, а не `400`. Исключение — `INVALID_JSON_BODY`: тело разбирается раньше проверки ключа, поэтому тело с синтаксической ошибкой JSON получает `400` до всех остальных отказов. Отказы `FQDN_FORBIDDEN` и `DOMAIN_TAKEN_EXTERNAL` приходят последними: их даёт реестр доменов, к которому платформа обращается после собственных проверок.
- **Имя окончательно закрепляется при проверке.** Привязка закрывает имя для других серверов платформы, но в реестре доменов Битрикс24 оно занимается только после успешной [проверки](./verify.md). Если между привязкой и проверкой имя подключат к другому продукту Битрикс24, отказ `DOMAIN_TAKEN_EXTERNAL` вернёт уже проверка.
- **Записи можно получить повторно.** Массив `instructions` с тем же значением `TXT` в любой момент отдаёт [`GET /v1/infra/servers/:id/domain`](./get.md), сохранять ответ привязки не обязательно.

## Смотрите также

- [Получить домен](./get.md)
- [Проверить домен](./verify.md)
- [Отвязать домен](./detach.md)
- [Свой домен](/docs/infra/domain)
- [Список серверов](/docs/infra/servers/list)
