Тема
Управление доменом
Сначала получите GET /domains/{domainUuid} и GET /domains/{domainUuid}/capabilities. Capabilities описывают возможности драйвера, но не гарантируют достаточный баланс, scope или допустимое состояние реестра. Во всех изменяющих запросах требуется Idempotency-Key; для операций управления также reason длиной 3..1000 символов.
Асинхронная операция
Обычно изменяющий запрос возвращает HTTP 202:
json
{
"data": {
"uuid": "66666666-6666-4666-8666-666666666666",
"domain_uuid": "55555555-5555-4555-8555-555555555555",
"action": "renew",
"status": "pending",
"result": [],
"error": null,
"created_at": "2026-10-05T09:00:00+00:00",
"completed_at": null,
"next_check_at": "2026-10-05T09:00:00+00:00"
}
}Читайте GET /operations/{operationUuid}. История доступна через GET /domains/{domainUuid}/operations, включая историю удалённого домена. Оба метода требуют domains.read. Повтор первоначального POST с прежним ключом воспроизводит первоначальный ответ, а не текущий прогресс.
| Статус | Обработка |
|---|---|
pending, processing | Продолжать ожидание с ограниченной частотой. |
completed | Прочитать итоговый Domain; не вычислять срок регистрации самостоятельно. После удаления обычный GET домена может вернуть 404: результат и история операции остаются отдельными источниками состояния. |
failed | Проверить error.code и причину; новая попытка возможна только после устранения причины и подтверждённого исхода. |
uncertain | Команда могла выполниться. Не отправлять её заново и не освобождать свой резерв автоматически. |
cancelled или неизвестный статус | Не считать успехом. Сохранить состояние для сверки; универсального метода отмены операции нет. |
next_check_at обозначает план серверной проверки, а не гарантированный срок завершения. При failed поле completed_at может оставаться null; пустой result сериализуется как [], а заполненный обычно как объект. uncertain также используется при ожидании завершения переноса или восстановления в реестре, не только после потери ответа. Неизвестный результат может потребовать помощи оператора, особенно при изменении контактов, приватности или получении auth code.
Продление
- Получите срок домена и
renewal_available_atиз capabilities. - Выпустите quote с
operation: renewиpayload.domain_service_uuidравным UUID домена. - Отправьте
POST /domains/{domainUuid}/renewс UUID quote и причиной. - Дождитесь
completedи перечитайтеexpires_at.
json
{
"customer_uuid":"11111111-1111-4111-8111-111111111111",
"items":[{
"resource_type":"domain_zone",
"resource_uuid":"22222222-2222-4222-8222-222222222222",
"operation":"renew",
"period_unit":"year",
"period_count":1,
"quantity":1,
"currency":"KZT",
"payload":{"domain_service_uuid":"55555555-5555-4555-8555-555555555555"}
}]
}Тело запроса продления:
json
{"quote_uuid":"44444444-4444-4444-8444-444444444444","reason":"Продление по оплаченному заказу customer-order-1002"}Период задаётся целыми годами. Максимальный суммарный срок учитывает уже оставшееся время и не может превышать 10 лет; доступные периоды дополнительно ограничены зоной и предложением. После регистрации должно пройти не менее 24 часов. Указание period_count: 10 не означает, что десять лет разрешены любому уже действующему домену. Реестр может накладывать дополнительные ограничения.
Автопродление
PUT /domains/{domainUuid}/auto-renew:
json
{"enabled":true,"reason":"Согласие владельца на ежегодное продление по текущему тарифу"}Ответ 200 сохраняет настройку и не продлевает домен немедленно. API-автопродление выключено по умолчанию, работает для external checkout и использует период один год по текущей цене. Проверяйте его флаг через data.auto_renew в capabilities: одноимённый флаг общей услуги /services относится к другому механизму. Планировщик ежечасно выбирает зарегистрированные домены с окончанием не позднее чем через семь дней, включая уже просроченные; допустимость продления дополнительно проверяется политикой домена и реестром. Это не SLA выполнения реестром.
Следите за domain.auto_renew.failed и domain.operation.updated: недостаток средств, отзыв ключа или отсутствие цены требуют вмешательства. Выключение enabled: false не отменяет уже принятую операцию. При ротации/замене доступа проверьте работоспособность автопродления с оператором.
Входящий перенос
Для домена, которого ещё нет среди ваших услуг, получите quote operation: transfer, period_unit: year, period_count: 1, quantity: 1. В payload укажите domain_name в ASCII/Punycode, external_id и все четыре contact_uuids, как при регистрации. Затем:
POST /domains/transfers:
json
{
"quote_uuid":"44444444-4444-4444-8444-444444444444",
"customer_uuid":"11111111-1111-4111-8111-111111111111",
"auth_code":"REPLACE_WITH_REAL_TRANSFER_CODE",
"reason":"Входящий перенос по заявке владельца"
}В aggregate customer_uuid опускается. Ответ 202 содержит операцию и domain_uuid. При переносе уже существующего локального домена используется POST /domains/{domainUuid}/transfer, а quote привязывается через payload.domain_service_uuid.
Перенос может ожидать подтверждения несколько дней по правилам реестра. Для проверки и управления доступны POST /transfer/query, /transfer/approve, /transfer/reject, /transfer/cancel относительно домена с телом {"reason":"Причина действия владельца"}. Не путайте отмену переноса с отменой любой асинхронной задачи.
Один год в quote является единицей тарификации переноса, а не обещанием прибавить год во всех реестрах. NS из quote входящего переноса не применяются: при необходимости измените их отдельной операцией после завершения.
Исходящий перенос и auth code
При согласии владельца снимите clientTransferProhibited, если это допустимо, и вызовите POST /domains/{domainUuid}/auth-code. Секрет появляется не в исходном 202, а в GET /operations/{operationUuid} как data.result.auth_code, только если ключ имеет domains.auth-code и domains.read.
Не записывайте auth code в логи, аналитику, тикеты или общий кэш. Ответы чтения операций имеют Cache-Control: no-store. Запрос на перенос подаёт принимающий регистратор; отдельного публичного метода «перенести к произвольному регистратору» здесь нет.
Восстановление удалённого домена
Возможность восстановления определяется реестром. Quote использует operation: restore, один год, количество один и payload.domain_service_uuid; для своего soft-deleted домена этот сценарий предусмотрен. Нужен отдельный настроенный тариф восстановления.
POST /domains/{domainUuid}/restore:
json
{
"quote_uuid":"44444444-4444-4444-8444-444444444444",
"restore_auth":"REPLACE_WITH_REGISTRY_VALUE",
"reason":"Восстановление по подтверждённой заявке владельца"
}Обязательно хотя бы одно непустое restore_auth или restore_password; нужное поле уточняется для регистратора. Не угадывайте секрет и не считайте срок доступности восстановления одинаковым для всех зон. Результат 202 отслеживается как обычная операция.
NS, контакты и блокировки
Все следующие примеры являются телами запросов относительно /domains/{domainUuid} и возвращают 202.
| Метод | Тело |
|---|---|
PUT /nameservers | {"nameservers":[{"hostname":"ns1.example.net"},{"hostname":"ns2.example.net"}],"reason":"Смена DNS-провайдера"} |
PUT /contacts | {"contacts":{"owner":"33333333-3333-4333-8333-333333333333","admin":"33333333-3333-4333-8333-333333333333","tech":"33333333-3333-4333-8333-333333333333","billing":"33333333-3333-4333-8333-333333333333"},"reason":"Смена контактных ролей"} |
PUT /statuses | {"add":["clientTransferProhibited"],"remove":[],"reason":"Запрет переноса владельцем"} |
PUT /whois-privacy | {"enabled":true,"hidden_fields":["address","phone","email"],"reason":"Защита контактных данных"} |
POST /sync | {"reason":"Сверка с состоянием реестра"} |
NS заменяются полным набором из 2..6 уникальных имён; optional ipv4/ipv6 должны соответствовать семейству IP. Имена нормализуются, различие регистра не создаёт разные NS.
Контактные роли передаются полностью. Изменение профиля через PATCH /contacts/{contactUuid} и назначение роли через PUT /domains/{domainUuid}/contacts являются разными действиями. PATCH контакта требует обязательных полей полной формы, а не произвольного частичного объекта. Не обещайте немедленное обновление всех реестровых объектов от локального редактирования контакта.
Разрешены только clientTransferProhibited, clientUpdateProhibited, clientDeleteProhibited, clientRenewProhibited, clientHold. Один статус нельзя добавлять и удалять одновременно. serverHold и другие server-статусы этим методом не снимаются. Приватность зависит от зоны и регистратора; список полей: name, organization, address, phone, fax, email.
Собственные NS: glue hosts
| Метод | Тело или query |
|---|---|
POST /hosts | {"hostname":"ns1.example.kz","ipv4":"192.0.2.10","ipv6":"2001:db8::10","reason":"Создание собственного NS"} |
GET /hosts | ?hostname=ns1.example.kz |
PUT /hosts | {"hostname":"ns1.example.kz","add_addresses":["192.0.2.11"],"remove_addresses":["192.0.2.10"],"reason":"Обновление адреса NS"} |
DELETE /hosts | {"hostname":"ns1.example.kz","reason":"Удаление неиспользуемого NS"} |
Разрешены только имена, подчинённые этому домену. При создании нужен хотя бы один IP; при изменении не более 10 адресов в каждом массиве. Эквивалентные формы IPv6 также считаются одним адресом при проверке пересечений. GET возвращает сведения об одном host, а не список DNS-записей или всех NS реестра.
Удаление
DELETE /domains/{domainUuid}:
json
{"confirm_domain":"example.kz","reason":"Удаление по документированному запросу владельца"}confirm_domain должен точно совпадать с domain_name из GET, включая форму IDN. Получите явное согласие владельца в своём интерфейсе. HTTP 202 не означает немедленное освобождение имени; последствия и возможность восстановления определяются реестром. Это не удаление только локальной записи биллинга.
Подтверждение владельца ЭЦП
- Получите
GET /domains/{domainUuid}/registrant-verification/payloadсо scopedomains.verify. - Передайте точный
signable_payloadв NCALayer с возвращёнными параметрами. Не пересобирайте документ из snapshot. - Подпишите действующей ЭЦП надлежащего владельца/уполномоченного подписанта. Закрытый ключ и пароль не отправляются в API.
- Отправьте
POST /domains/{domainUuid}/registrant-verificationс новым идемпотентным ключом.
json
{
"type":"eds",
"eds_provider":"ncalayer",
"payload_snapshot":{"REPLACE":"exact object returned by payload endpoint"},
"signable_payload":"REPLACE_WITH_EXACT_RETURNED_STRING",
"signature":"REPLACE_WITH_BASE64_DER_CMS",
"signature_options":{
"method":"kz.gov.pki.knca.basics.sign",
"format":"cms",
"decode":false,
"encapsulate":false,
"digested":false,
"timestamp_applied":true,
"cms_type":"CMS Detached",
"cades_profile":"CAdES-T"
}
}Это шаблон связывания полей, а не готовая подпись: payload_snapshot, signable_payload и signature_options берутся из свежего ответа без изменений; signature является результатом подписания. Требуется detached CAdES-T с меткой времени, Base64 DER CMS без PEM. Проверяйте expires_at, обычно payload действует 15 минут.
Ответ 201 содержит Verification, не Operation. Прогресс проверяется через Domain и событие domain.verification.updated; отдельного GET verification по UUID нет. При принятой pending-заявке повторное подписание не требуется. Успешная ЭЦП не гарантирует прохождение независимой проверки образовательной лицензии .edu.kz; её статус проверяется отдельно.