Перейти к основному содержимому

Справочник API

Базовый URL: https://api.nexdns.ru/v1

Аутентификация

Все API-запросы требуют аутентификации с помощью API-ключа. Передавайте ключ в заголовке Authorization как Bearer-токен. API-ключ должен начинаться с префикса nxd_.

Требования к тарифу: REST API, API, совместимый с ISPmanager, и вебхуки доступны на тарифе Про и выше – как и две возможности, которые тоже описаны в этом справочнике: DNSSEC и вторичные (slave) зоны. Ключ на тарифе без них получает ответ 403.

Authorization: Bearer nxd_your_api_key_here

API работает без сохранения состояния – каждый запрос аутентифицируется независимо. Сессии и cookies не используются.

Храните API-ключ в секрете. Не передавайте его в клиентском коде, публичных репозиториях или URL-адресах. Если ключ скомпрометирован, немедленно отзовите его и создайте новый.

Ошибки аутентификации

Статус Причина
401 Отсутствующий или недействительный API-ключ, истёкший ключ или отменённый аккаунт
403 У ключа нет разрешения, которое требует эндпоинт, либо тариф аккаунта не включает доступ к API – проверка тарифа отвечает 403, а не 401, на любом пути.

Формат ответа

Все ответы возвращаются в формате JSON. Успешные ответы имеют следующую структуру:

Единичный ресурс

{
    "status": "success",
    "data": {
        "id": "xK9mQ2",
        "name": "example.com",
        ...
    }
}

Список с пагинацией

{
    "status": "success",
    "data": [ ... ],
    "meta": {
        "total": 150,
        "page": 1,
        "per_page": 25,
        "last_page": 6
    }
}

Ответ с ошибкой

{
    "status": "error",
    "error": {
        "code": "validation_error",
        "message": "Validation failed.",
        "details": {
            "name": ["Domain name is required."]
        }
    }
}

Ошибки, возникающие глубже в платформе – лимит тарифа, заблокированный домен, недоступность DNS-серверов – содержат тот же объект error, но без поля status. Ветвите логику по error.code: он стабилен, в отличие от наличия поля status. Сообщения по контракту всегда на английском, на любом экземпляре и в любой локали; машиночитаемая часть – это error.code.

Публичные ID

Каждый ресурс идентифицируется непрозрачным id (например, xK9mQ2), который используется в URL-путях. Числовые ID из базы данных никогда не раскрываются и не принимаются.

Пагинация

Эндпоинты списков, возвращающие постраничные результаты, принимают следующие параметры запроса:

Параметр Тип По умолчанию Описание
page integer 1 Номер страницы (минимум 1)
per_page integer 25 Элементов на странице (1–100)

Лимиты запросов

Запросы считаются на аккаунт, а не на ключ, в скользящем окне длиной одну минуту; размер лимита определяется тарифом – точное значение есть в сравнении тарифов на странице цен. Запросы без аутентификации считаются по IP-адресу. Текущее состояние лимита возвращается в каждом ответе, поэтому угадывать не нужно:

Заголовок Значение
X-RateLimit-LimitСколько запросов разрешено в окне.
X-RateLimit-RemainingСколько запросов осталось в текущем окне.
X-RateLimit-ResetUnix-время, когда начинается новое окно.
Retry-AfterСколько секунд подождать; передаётся в ответе 429.

При массовых операциях – импорте большой зоны, сверке сотен записей – читайте X-RateLimit-Remaining и делайте паузу до того, как счётчик дойдёт до нуля, вместо повторов после 429. CLI делает это за вас.

У некоторых операций поверх лимита запросов есть собственное, более длинное окно: одну зону можно перенести в другую группу DNS-серверов три раза в сутки. В ответе указано, какой лимит исчерпан.

Зоны

Управление DNS-зонами. Требуется zones.read для операций чтения и zones.write для операций записи.

GET /v1/zones

Список всех зон аутентифицированного пользователя.

Параметры запроса

  • search – фильтрация зон по имени
  • page, per_page – пагинация

Поля ответа

id, name, type (master или slave), status, ns_group, created_at, updated_at

GET /v1/zones/{id}

Получение подробной информации о конкретной зоне, включая SOA-данные, серверы имён и количество записей.

Дополнительные поля ответа

records_count, soa (primary_ns, admin_email, serial, refresh, retry, expire, minimum), nameservers (массив), ns_group (id, slug, name)

POST /v1/zones

Создание новой DNS-зоны. Отклоняется с кодом 409, если домен уже существует или пересекается с зоной другого аккаунта, и с кодом 422, если достигнут лимит зон тарифа или домен заблокирован.

Тело запроса (JSON)

{
    "name": "example.com",
    "type": "master",
    "ns_group": "eu"
}

Вторичная (slave) зона:

{
    "name": "example.com",
    "type": "slave",
    "master_ip": "203.0.113.10"
}
  • name (обязательно) – доменное имя
  • type"master" (по умолчанию) или "slave"
  • ns_group – группа NS для назначения зоны (необязательно, используется группа по умолчанию)
  • master_ip – обязательно для вторичных (slave) зон; должен быть корректным публичным IP-адресом

Возвращает 201 Created с объектом зоны.

PATCH /v1/zones/{id}

Перенос зоны в другую группу DNS-серверов. Это единственный PATCH в API. Разрешение: zones.write.

Тело запроса (JSON)

{
    "ns_group": "ru"
}

Возвращает зону в состоянии после переноса, в том же формате, что и GET /v1/zones/{id}. Группа указывается по её slug – это значения, которые перечисляет для вашего аккаунта GET /v1/ns-groups; любое другое значение отклоняется с кодом 400.

Зона продолжает отвечать всё время переноса: новые DNS-серверы готовятся до отправки ответа, а прежние обслуживают запросы, пока обновляются кеши резолверов. После переноса обновите делегирование у регистратора. Зону можно перенести три раза в сутки; сверх этого запрос вернёт 429.

DELETE /v1/zones/{id}

Удаление зоны и всех её записей.

Возвращает 204 No Content при успехе.

GET /v1/zones/{id}/export

Экспорт зоны в формате BIND или в структурированном JSON.

Параметры запроса

  • format"bind" (по умолчанию) возвращает текст зонного файла BIND; "json" возвращает структурированный массив записей с полями name, type, content и ttl

Записи

Управление DNS-записями в зоне. Все эндпоинты записей вложены в зону. Требуется records.read для операций чтения и records.write для операций записи.

GET /v1/zones/{zoneId}/records

Список всех записей в зоне.

Параметры запроса

  • type – фильтрация по типу записи (например, A, CNAME, MX)
  • name – фильтрация по имени записи (поиск подстроки)
  • search – поиск по имени и содержимому

Поля ответа

id, name, type, content, ttl, disabled, fields (специфичные для типа поля)

GET /v1/zones/{zoneId}/records/{recordId}

Получение одной записи по её ID.

POST /v1/zones/{zoneId}/records

Создание новой DNS-записи.

Тело запроса (JSON)

{
    "type": "A",
    "name": "www",
    "ttl": 3600,
    "content": "93.184.216.34"
}
  • type (обязательно) – тип записи (A, AAAA, CNAME, MX, TXT, SRV, CAA, NS, PTR, ALIAS, DNAME, DS, TLSA)
  • name – имя записи относительно зоны (по умолчанию: @ – вершина зоны)
  • ttl – время жизни в секундах (по умолчанию: 3600)
  • content – значение записи (IP для A/AAAA, имя хоста для CNAME/NS/PTR, текст для TXT, почтовый сервер для MX)

Поля для конкретных типов

  • MX: priority (по умолчанию: 10)
  • SRV: поля priority, weight, port
  • CAA: flags (по умолчанию: 0), tag (по умолчанию: "issue")
  • DS: поля keytag, algorithm, digest_type
  • TLSA: поля usage, selector, matching_type

Для MX, SRV, CAA, DS и TLSA в content передаётся только основное значение – почтовый хост, цель SRV, домен удостоверяющего центра, сам hex-отпечаток – всё остальное указывается в полях выше. Собранная вручную строка записи (например, 0 issue "letsencrypt.org" в качестве content для CAA) отклоняется с кодом 400 и указанием поля.

TTL относится ко всему набору записей. Если вы добавляете ещё одно значение к уже существующему имени и не передаёте ttl, текущий TTL сохраняется; если передаёте – он применяется ко всем значениям этого имени. Для нового имени по умолчанию 3600 секунд.

Возвращает 201 Created с объектом записи.

PUT /v1/zones/{zoneId}/records/{recordId}

Обновление существующей записи. Укажите только поля, которые хотите изменить; остальные сохранят текущие значения.

{
    "content": "93.184.216.35",
    "ttl": 7200
}

Возвращает 200 OK с обновлённым объектом записи. Примечание: ID записи может измениться после обновления, так как он вычисляется из имени, типа и содержимого записи.

DELETE /v1/zones/{zoneId}/records/{recordId}

Удаление записи из зоны.

Возвращает 204 No Content при успехе.

DNSSEC

Управление DNSSEC для ваших зон. Требуется zones.read для просмотра статуса и zones.write для включения или отключения.

GET /v1/zones/{id}/dnssec

Получение статуса DNSSEC для зоны, включая ключи и DS-записи.

Поля ответа

enabled (boolean), keys (массив DNSKEY-записей), ds_records (массив DS-записей для установки у регистратора)

POST /v1/zones/{id}/dnssec/enable

Включение DNSSEC для зоны. Ключи подписи генерируются автоматически.

Возвращает статус DNSSEC с сгенерированными ключами и DS-записями.

POST /v1/zones/{id}/dnssec/disable

Отключение DNSSEC для зоны. Удаляет все ключи подписи.

Возвращает {"enabled": false, "keys": [], "ds_records": []}.

NS-группы

Список доступных групп DNS-серверов. Используйте id группы как ns_group при создании зоны. Эндпоинт доступен по любому действующему API-ключу.

GET /v1/ns-groups

Список активных групп DNS-серверов.

Поля ответа для каждой группы

id, name, slug

Аккаунт

Просмотр информации об аккаунте и управление API-ключами.

GET /v1/account

Получение информации о текущем аккаунте, включая данные подписки.

Поля ответа

Поля id (UUID), email, name, role, status, language, timezone, created_at.

subscription – объект с полями plan, billing_cycle, status, current_period_start, current_period_end (или null при отсутствии подписки)

GET /v1/account/api-keys

Список всех API-ключей аутентифицированного пользователя.

Поля ответа для каждого ключа

id, name, key_prefix (первые 8 символов), permissions (массив), last_used_at, expires_at, created_at

POST /v1/account/api-keys

Создание нового API-ключа.

Тело запроса (JSON)

{
    "name": "CI/CD Pipeline",
    "permissions": ["zones.read", "records.read", "records.write"],
    "expires_at": "2027-01-01"
}
  • name (обязательно) – понятное имя (максимум 255 символов)
  • permissions (обязательно) – массив разрешений (минимум одно): zones.read, zones.write, records.read, records.write, webhooks.read, webhooks.write
  • expires_at – необязательная дата истечения (ISO 8601 или YYYY-MM-DD); должна быть в будущем

Ответ содержит полный API-ключ в поле key. Это единственный раз, когда полный ключ возвращается. Сохраните его в надёжном месте.

Возвращает 201 Created с данными ключа, включая полное значение key.

DELETE /v1/account/api-keys/{id}

Отзыв (безвозвратное удаление) API-ключа.

Возвращает 204 No Content при успехе.

Биллинг

Просмотр подписки, тарифных планов и счетов. Эти эндпоинты доступны только для чтения.

GET /v1/billing/subscription

Получение данных текущей подписки. Возвращает null при отсутствии активной подписки.

Поля ответа

Поля id, plan, billing_cycle, status, current_period_start, current_period_end, created_at.

GET /v1/billing/plans

Список всех доступных тарифных планов с ценами и функциями.

Поля ответа для каждого плана

id, name, slug, description, price_monthly, price_yearly, currency, max_domains, max_records, features (массив)

GET /v1/billing/invoices

Список счетов аутентифицированного пользователя, сначала новые.

Параметры запроса

  • status – фильтрация по статусу (draft, issued, sent, void)
  • page, per_page – пагинация

GET /v1/billing/invoices/{id}

Получение одного счёта по его <code>id</code>.

Поля ответа

Поля id, number, status, amount (итоговая сумма), net_amount (без налога), tax_amount, tax_rate, currency, issued_at, created_at. Денежные значения передаются строками с десятичной точкой.

Webhooks

Управление исходящими webhook-подписками для получения уведомлений об изменениях зон и записей в реальном времени. Требует webhooks.read для чтения и webhooks.write для создания, изменения и удаления.

GET /v1/webhooks

Список всех webhook-подписок аутентифицированного пользователя.

Поля ответа для каждой подписки

id, url, events (массив), description, is_active, failure_count, last_triggered_at, created_at

POST /v1/webhooks

Создание webhook-подписки.

Тело запроса (JSON)

{
    "url": "https://example.com/webhook",
    "events": ["zone.created", "record.created"],
    "description": "Production webhook"
}
  • url (обязательно) – HTTPS-адрес, на который будут отправляться данные событий
  • events (обязательно) – массив типов событий для подписки
  • description – необязательная понятная метка

Ответ содержит secret для проверки подписи webhook (HMAC). Это единственный раз, когда secret возвращается. Сохраните его в надёжном месте.

Возвращает 201 Created с id и secret подписки.

GET /v1/webhooks/{id}

Получение одной webhook-подписки вместе с последними доставками.

PUT /v1/webhooks/{id}

Изменение webhook-подписки. Указывайте только те поля, которые нужно изменить.

Возвращает 200 OK с обновлённым объектом подписки.

DELETE /v1/webhooks/{id}

Удаление webhook-подписки.

Возвращает 204 No Content при успехе.

POST /v1/webhooks/{id}/test

Отправка тестового события на адрес webhook для проверки доступности.

Ставит в очередь тестовую доставку с данными "type": "test".

Проверка доставки

Каждая доставка подписывается секретом, который возвращается при создании подписки, и содержит четыре заголовка:

X-NexDNS-Signature: sha256=<hmac>
X-NexDNS-Timestamp: 1785370265
X-NexDNS-Event: record.created
X-NexDNS-Delivery: 42

Вычислите HMAC-SHA256 по телу запроса в исходном виде, используя свой секрет, и сравните результат с hex-отпечатком после sha256= – сравнением за постоянное время. Несовпадение означает, что запрос пришёл не от нас. Заголовок X-NexDNS-Delivery идентифицирует попытку: повторные доставки одного события имеют одинаковый id события, но разные номера доставки.

Данные доставки

{
    "id": "evt_szpj9u04z8u0",
    "type": "record.created",
    "created_at": "2026-07-30 00:31:05",
    "data": {
        "zone": { "name": "example.com" },
        "record": { "name": "www.example.com.", "type": "A", "content": "203.0.113.10", "ttl": 3600 }
    }
}

Доступные типы событий

Можно подписаться на любую комбинацию этих типов событий:

zone.created, zone.updated, zone.deleted, record.created, record.updated, record.deleted, dnssec.enabled, dnssec.disabled, zone.health.problem, zone.health.resolved

Коды ошибок

Все ошибки имеют единый формат со строковым code ошибки и понятным message.

HTTP-статус Код ошибки Описание
400 validation_error Тело запроса не прошло валидацию. Проверьте details для ошибок по отдельным полям.
401 unauthorized Отсутствующий, недействительный или истёкший API-ключ.
403 forbidden У API-ключа нет нужного разрешения, тариф аккаунта не включает доступ к API, либо тариф не включает используемую возможность (например, вторичные зоны или DNSSEC).
404 not_found Запрашиваемый ресурс не существует или недоступен для аутентифицированного пользователя.
409 conflict Ресурс уже существует (например, дубликат имени зоны).
422 quota_exceeded Достигнут лимит зон или записей вашего тарифа.
422 domain_blacklisted Домен находится в списке заблокированных, добавить его нельзя.
429 rate_limit_exceeded Слишком много запросов. Проверьте заголовок Retry-After.
500 server_error Произошла непредвиденная внутренняя ошибка. Повторите попытку или обратитесь в поддержку, если она повторяется.
502 dns_server_error DNS-серверы временно недоступны. Запрос не применён, повторите его.

Примеры кода

Все примеры используют curl. Замените nxd_your_api_key на ваш настоящий API-ключ.

Список зон

curl -s "https://api.nexdns.ru/v1/zones" \
    -H "Authorization: Bearer nxd_your_api_key"

Создание зоны

curl -s -X POST "https://api.nexdns.ru/v1/zones" \
    -H "Authorization: Bearer nxd_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{"name": "example.com"}'

Добавление A-записи

curl -s -X POST "https://api.nexdns.ru/v1/zones/{zoneId}/records" \
    -H "Authorization: Bearer nxd_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
        "type": "A",
        "name": "www",
        "ttl": 3600,
        "content": "93.184.216.34"
    }'

Добавление MX-записи

curl -s -X POST "https://api.nexdns.ru/v1/zones/{zoneId}/records" \
    -H "Authorization: Bearer nxd_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
        "type": "MX",
        "name": "@",
        "ttl": 3600,
        "content": "mail.example.com",
        "priority": 10
    }'

Обновление записи

curl -s -X PUT "https://api.nexdns.ru/v1/zones/{zoneId}/records/{recordId}" \
    -H "Authorization: Bearer nxd_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{"content": "93.184.216.35", "ttl": 7200}'

Удаление записи

curl -s -X DELETE "https://api.nexdns.ru/v1/zones/{zoneId}/records/{recordId}" \
    -H "Authorization: Bearer nxd_your_api_key"

Экспорт зоны (формат BIND)

curl -s "https://api.nexdns.ru/v1/zones/{zoneId}/export" \
    -H "Authorization: Bearer nxd_your_api_key"

Включение DNSSEC

curl -s -X POST "https://api.nexdns.ru/v1/zones/{zoneId}/dnssec/enable" \
    -H "Authorization: Bearer nxd_your_api_key"

Создание API-ключа

curl -s -X POST "https://api.nexdns.ru/v1/account/api-keys" \
    -H "Authorization: Bearer nxd_your_api_key" \
    -H "Content-Type: application/json" \
    -d '{
        "name": "Read-only key",
        "permissions": ["zones.read", "records.read"],
        "expires_at": "2027-12-31"
    }'

Информация об аккаунте

curl -s "https://api.nexdns.ru/v1/account" \
    -H "Authorization: Bearer nxd_your_api_key"

Мы используем файлы cookie и метрические программы (Яндекс Метрика) для анализа посещаемости, улучшения работы сайта и оценки эффективности рекламы. Метрические программы собирают данные о вашем поведении на сайте, которые являются персональными данными. Обработка осуществляется в соответствии с законодательством о персональных данных (ФЗ-152).

Вы можете принять использование всех файлов cookie или ограничиться только необходимыми. Подробнее: Политика обработки персональных данных и Политика cookie.

Необходимые cookie (всегда активны)
Аналитические cookie (Яндекс Метрика)