Регистрация тем же движком и по тем же ценам, что на сайте, с лимитом трат на ключ.
Мои домены
Список доменов, сроки оплаты, NS и можно ли выставить на продажу.
Продажа доменов
Выставляйте домены, меняйте цену и описание, снимайте с продажи.
Купил — выставил
Номер заказа из ответа на покупку сразу выставляет домен в магазин, а ИИ пишет карточку на русском и английском.
История продаж
Продажи, комиссия площадки и сколько зачислено на баланс.
Поиск по магазину
Публичный поиск лотов с фильтрами — без токена.
API работает с сервера: ваш скрипт, бот или сервис (например, HQName) обращается к HQClouds по HTTPS с токеном из кабинета. Все суммы — в USD, деньги списываются с баланса HQClouds.
Быстрый старт
Войдите или зарегистрируйтесь в HQClouds. Если собираетесь покупать домены — пополните баланс и один раз заполните контакты владельца домена (WHOIS): контакты WHOIS.
В кабинете откройте раздел «API» и создайте ключ: название, права и дневной лимит трат.
Скопируйте токен — он показывается только один раз. Сохраните его в переменной окружения или менеджере секретов.
Токен показывается один раз при создании. Мы храним только его хэш — восстановить токен нельзя, только выпустить новый.
Не вставляйте токен в код сайта или мобильного приложения: API рассчитано на вызовы с сервера, CORS для него закрыт.
Если токен утёк — отзовите ключ в кабинете: отзыв действует сразу.
Тело запроса — JSON (Content-Type: application/json) или обычная форма. Для PATCH форма — только application/x-www-form-urlencoded.
Сообщения об ошибках — на английском; с заголовком Accept-Language: ru большинство придёт на русском. Поле code от языка не зависит — в коде опирайтесь на него.
Ссылки url в ответах ведут на страницу сайта на том же языке, что и сообщения.
Карточка лота card (заголовок, описание, «подойдёт для») — тоже на языке ответа: с ?lang=ru или Accept-Language: ru — по-русски, иначе по-английски. Так вы видите ровно то, что увидит покупатель на этом языке.
Права ключа
Права задаются при создании ключа. Давайте ключу только то, что нужно программе.
Право
Что разрешает
read
Есть у каждого ключа. Чтение: аккаунт и баланс, домены, заказы, лоты, продажи, проверка доменов.
market:write
Выставлять, изменять и снимать лоты в магазине доменов, заказывать для них ИИ-описание.
domains:register
Покупать домены с баланса. Требует дневной лимит трат.
Лимиты
60запросов в минуту на ключ. Сверх лимита — 429 и заголовок Retry-After; остаток виден в X-RateLimit-Remaining.
$100дневной лимит трат по умолчанию — свой задаётся при создании ключа. Считается за последние 24 часа.
20покупок доменов в час на ключ — защита от ошибки в цикле скрипта.
10действующих ключей на аккаунт: отозванные и истёкшие не считаются.
Покупки выполняются строго по одной: если в этот момент идёт другая покупка, придёт 429 busy — повторите через несколько секунд с тем же Idempotency-Key.
Премиум-домены через API не продаются никогда — только вручную в кабинете.
Публичный поиск по магазину: 60 запросов в минуту с одного IP.
ИИ-описания лотов: одновременно — не больше 2 генераций на аккаунт, число генераций тоже ограничено. Сверх лимита — 429 ai_rate_limited с Retry-After, лот при этом остаётся в продаже.
Безопасность ключей
Токен с правом покупки — это доступ к вашему балансу. Вот что его защищает и как не потерять его самому.
Разрешённые IP
При создании ключа укажите адреса серверов, с которых он работает: IPv4, IPv6 или подсеть (например, 203.0.113.0/24 или 2001:db8::/48), до 20 штук.
Запрос с любого другого адреса получает 403 ip_not_allowed, даже с верным токеном: утёкшим токеном с чужого сервера не воспользоваться. Это дополнительная защита, а не замена секретности токена — храните его как пароль.
Из Cloudflare Workers и похожих платформ без своего постоянного адреса список IP не подходит: выпустите для них отдельный ключ без списка, с минимальными правами и дневным лимитом.
Список не задан — ключ работает с любого адреса. Изменить список нельзя: выпустите новый ключ и отзовите старый.
Защита от перебора
Неудачный вход — запрос без токена, с неверным, отозванным или истёкшим токеном или не с разрешённого IP.
Больше 30 неудачных входов за минуту с одного IP — 429 too_many_auth_failures до конца минуты; больше 300 за час — до конца часа.
Для IPv6 считается и сам адрес, и вся его сеть /64 — у сети порог в 10 раз выше. Если сеть заблокирована из-за соседей, ключ со списком разрешённых IP, в который входит ваш адрес, продолжает работать.
Массовый перебор со многих адресов сразу мы тоже видим и разбираем вручную.
Ответ на неверный токен не зависит от того, существует ли такой ключ: по ответу и его времени ничего не угадать.
Деньги и выпуск ключей
Дневной лимит трат ключа с правом domains:register — не больше $1000. Он ограничивает ущерб, даже если токен утечёт.
Ключ с правом покупки выпускается только после ввода пароля аккаунта.
О каждом новом ключе на почту аккаунта приходит письмо: название, права, лимит, разрешённые IP и адрес, с которого его выпустили.
Выпустить можно не больше 10 ключей в час.
HTTP
code
Что значит
HTTP 401
unauthorized, invalid_token
Токена нет, он неверный, отозван или истёк. Считается неудачным входом.
HTTP 403
ip_not_allowed
Токен верный, но у ключа есть список разрешённых IP, а запрос пришёл с другого адреса. Адрес, который увидел сервер, — в сообщении и в поле ip.
HTTP 403
scope_required
У ключа нет нужного права — выпустите ключ с ним.
HTTP 429
too_many_auth_failures
С вашего IP слишком много неудачных входов: больше 30 за минуту или 300 за час. До конца окна запросы с этого IP не принимаются, время — в Retry-After.
HTTP 429
rate_limited
Превышен лимит запросов в минуту на ключ — подождите Retry-After секунд.
Как хранить ключи
Один ключ — одна интеграция: такой ключ можно отозвать, не ломая остальные.
Только нужные права: для выставления лотов не нужен domains:register, для чтения — ничего, кроме read.
Для серверных скриптов задавайте разрешённые IP.
Меняйте ключи регулярно: выпустите новый (можно со сроком действия), переключите программу, отзовите старый.
Никогда не вставляйте токен в JavaScript сайта, мобильное приложение или репозиторий — храните его в переменных окружения или менеджере секретов.
Пришло письмо о ключе, которого вы не выпускали, — сразу отзовите его и смените пароль.
Идемпотентность покупок
Сеть может оборваться в момент покупки — и вы не узнаете, прошла ли она. Поэтому каждая покупка требует заголовок Idempotency-Key: любую уникальную строку до 100 символов (латиница, цифры и - _ : .), например UUID.
Повтор с тем же ключом безопасен: API вернёт результат первой попытки и не спишет деньги второй раз.
Новый ключ — это новая покупка. Генерируйте ключ один раз на покупку и сохраняйте его до отправки запроса.
Таймаут, обрыв или ответ 5xx — повторяйте с тем же ключом. Ответ 202 — заказ у регистратора, деньги в резерве: не покупайте заново, а проверяйте GET /domains/{domain}.
Ответ на повтор помечен idempotent_replay: true. После 202 GET /domains/{domain} отвечает status: pending, пока регистратор работает, и status: failed с refunded: true, если регистрация не удалась.
Ключ уникален в пределах аккаунта: повтор с другим API-ключом того же аккаунта (например, после смены ключа) вернёт ту же покупку с пометкой other_api_key: true. Ключ длиннее 100 символов или с другими символами не обрезается, а отклоняется: 422 invalid_idempotency_key.
Повтор после отказа до регистратора или после 404 not_started — новая попытка: цена и лимиты трат проверяются заново. Idempotency-Key с первой попытки привязан к домену: тот же ключ с другим доменом — 422 idempotency_key_reused.
Ответ потерялся и номер заказа неизвестен — GET /domains/register/{Idempotency-Key}: 200 — заказ и его итог, 202 — покупка ещё идёт, 404 not_started — до регистратора не дошла, ничего не списано (повторите POST с тем же ключом). Этот запрос только читает: ничего не покупает и не списывает.
Все ответы — JSON в UTF-8. Успешный ответ содержит "ok": true. Ошибка — "ok": false и объект error с машинным кодом code и сообщением message. Суммы — строки с двумя знаками после точки. Списки отдают items и total, page, pages, per_page. Сумма покупки в ответе — ровно та, что зарезервирована или списана: если она не в целых центах, в строке будут все её знаки.
json
{
"ok": false,
"error": {
"code": "daily_limit",
"message": "Daily spend limit reached: spent $95.00 of $100.00 in the last 24 hours, this purchase is $12.99."
}
}
HTTP
code
Что значит
HTTP 200
already_listed
Не ошибка: домен уже выставлен — ответ 200 с тем же лотом и already_listed: true, ничего не изменено.
HTTP 400
invalid_json
Тело запроса — не JSON-объект.
HTTP 400
bad_request
Некорректный запрос: например, параметр в адресе неверного вида.
HTTP 401
unauthorized
Нет заголовка Authorization: Bearer.
HTTP 401
invalid_token
Токен неверный, отозван или истёк.
HTTP 402
insufficient_balance
Не хватает денег на балансе — пополните его в кабинете.
HTTP 403
ip_not_allowed
У ключа есть список разрешённых IP, а запрос пришёл с другого адреса (адрес — в поле ip).
HTTP 403
scope_required
У ключа нет нужного права.
HTTP 403
no_spend_limit
У ключа нет дневного лимита трат — покупать им нельзя.
HTTP 404
not_found
Нет такого адреса API, домена или лота — или он не ваш.
HTTP 404
order_not_found
Нет такого заказа — или он не ваш.
HTTP 404
not_started
Сверка по Idempotency-Key: покупка с этим ключом до регистратора не дошла, ничего не списано — повторите POST с тем же ключом.
HTTP 405
method_not_allowed
Этот адрес не поддерживает такой метод.
HTTP 409
registration_failed
Регистратор отказал уже после резерва — деньги вернулись на баланс (refunded: true).
HTTP 409
not_available
Домен занят или его доступность не удалось подтвердить — деньги не списаны. Повтор с тем же Idempotency-Key проверит домен заново.
HTTP 409
no_contact
Не заполнены контакты владельца домена (WHOIS) — заполните их один раз в кабинете.
HTTP 409
price_above_max
Итоговая цена выше max_price — покупка не сделана.
HTTP 409
price_changed
Цена выросла между проверкой запроса и резервом денег — покупка не сделана, ничего не списано. Новая цена — в error.price, проверенная — в error.confirmed_price.
HTTP 409
premium_not_allowed
Премиум-домен: только вручную в кабинете.
HTTP 409
…
Прочие отказы покупки до регистратора — деньги не списаны, причина в message.
HTTP 409
order_pending
Регистратор ещё обрабатывает заказ — выставить домен можно после регистрации. Повторите через Retry-After секунд.
HTTP 409
order_failed
Регистрация по заказу не удалась, деньги вернулись — выставлять нечего.
HTTP 409
domain_not_owned
Домена из заказа больше нет в вашем аккаунте: продан, передан или удалён.
HTTP 409
domain_not_real
Домен куплен в тестовом режиме (sandbox) и у регистратора не существует — выставить его на продажу нельзя.
HTTP 409
lot_not_active
Лот снят или продан — менять его и заказывать ИИ-описание нельзя.
HTTP 409
lot_reserved
Покупатель сейчас оплачивает домен — до конца брони лот нельзя менять, снимать и перегенерировать.
HTTP 409
ai_in_progress
ИИ-описание этого лота уже генерируется другим запросом — проверьте лот через Retry-After секунд.
HTTP 413
payload_too_large
Тело запроса больше 64 КБ.
HTTP 422
validation_failed
Ошибка в данных (цена, тематика, домен нельзя выставить и т. п.) — подробности в message.
Idempotency-Key длиннее 100 символов или с недопустимыми символами — ключ не обрезается, а отклоняется.
HTTP 422
idempotency_key_reused
Этот Idempotency-Key уже использован для покупки другого домена.
HTTP 422
invalid_max_price
max_price — не обычное число (например, 1e3, true или текст).
HTTP 422
years_unsupported
Через API доступна регистрация только на 1 год.
HTTP 422
quote_failed
Не удалось получить цену домена — подробности в message.
HTTP 422
invalid_status
Неизвестное значение фильтра status у списка лотов или заказов.
HTTP 422
nothing_to_update
В PATCH не передано ни одного поля для изменения.
HTTP 429
rate_limited
Превышен лимит запросов в минуту — подождите Retry-After секунд.
HTTP 429
too_many_auth_failures
С одного IP больше 30 неудачных входов за минуту или 300 за час (без токена, с неверным токеном, не с разрешённого IP) — запросы с этого IP не принимаются до конца окна, время — в Retry-After.
HTTP 429
daily_limit, hourly_limit
Исчерпан дневной лимит трат ключа или лимит покупок в час.
HTTP 429
busy
Сейчас идёт другая покупка — повторите через несколько секунд с тем же Idempotency-Key.
HTTP 429
ai_rate_limited
Лимит ИИ-генераций или слишком много генераций сразу — повторите через Retry-After секунд. Лот при этом остаётся в продаже.
HTTP 500
internal_error
Сбой на нашей стороне. Покупку повторяйте с тем же Idempotency-Key.
HTTP 502
ai_failed
Модель не дала годного описания — лот остаётся с прежним текстом (ИИ-описанием, если оно было, иначе автоописанием по правилам), повторите позже.
HTTP 503
api_disabled, market_disabled
API или магазин доменов временно выключены.
HTTP 503
ai_unavailable
ИИ-описания сейчас выключены — покупатели видят описание по правилам.
Эндпоинты
Пути указаны относительно базового адреса https://hqclouds.com/api/v1.
GET/me
Аккаунт, баланс и ключ
Кто владелец токена, сколько денег на балансе, какие права у ключа и сколько из дневного лимита уже потрачено. Удобно проверить токен перед работой.
Свободен ли домен и сколько стоят регистрация и продление. Ничего не покупает. Если домен продаётся в магазине HQClouds, в for_sale будут цена и ссылка.
Право: read
Параметр
Тип
Обязателен
Описание
domain
string
да
Имя домена, например example.com. Домены на кириллице принимаются как есть.
state: available — свободен, taken — занят, premium — премиум-домен (через API не продаётся), for_sale — продаётся в магазине HQClouds, unsupported_tld — зону мы не регистрируем, unknown — проверить не удалось, повторите позже.
Доступность — предварительная: окончательная проверка цены и наличия происходит в момент покупки.
{
"ok": true,
"domain": "example.com",
"state": "available",
"available": true,
"premium": false,
"price": {"register": "12.99", "renew": "14.99", "currency": "USD"},
"for_sale": null,
"note": "Availability is indicative; the final check happens at purchase."
}
POST/domains/register
Купить домен
Регистрирует домен на 1 год и списывает цену с баланса HQClouds. Перед списанием — та же финальная проверка цены, что и на сайте. Покупки выполняются по одной. Покупка ничего не выставляет на продажу: выставление — отдельный запрос POST /market/lots.
Право: domains:register
Параметр
Тип
Обязателен
Описание
Idempotency-Key
header
да
Уникальная строка на каждую покупку (до 100 символов). Подробно — в разделе «Идемпотентность покупок».
domain
string
да
Имя домена.
max_price
number
нет
Не покупать, если итоговая цена выше этой суммы, USD: обычное число, например 15 или 14.99. Рекомендуем передавать всегда.
years
integer
нет
Срок регистрации. Через API доступен только 1 год.
Перед первой покупкой один раз заполните контакты владельца домена (WHOIS) в кабинете — без них придёт 409 no_contact.
201 — домен зарегистрирован и уже ваш. 202 — регистратор ещё обрабатывает заказ: деньги зарезервированы, не покупайте заново, а проверяйте GET /domains/{domain} раз в минуту-две, пока status не станет active (домен ваш) или failed (не удалось, деньги вернулись на баланс).
409 registration_failed — регистратор отказал уже после резерва: деньги вернулись на баланс (refunded: true), резерв дневного лимита освобождён. Это конечный исход: позже по этой заявке ничего не спишется, и новую покупку того же домена можно начинать сразу (с новым Idempotency-Key). Другие отказы (домен занят, цена выше max_price) тоже ничего не списывают.
Если попытка дошла до регистратора, повтор с тем же Idempotency-Key отвечает её итогом с пометкой idempotent_replay: true — 201 с ценой, 202 или 409 registration_failed — и ничего не списывает. Отказ до регистратора (домен занят, баланс, max_price, лимит) можно повторить с тем же ключом.
Номер заказа — order.id (dq_…): он есть в каждом ответе, где покупка дошла до регистратора (201, 202, 409 registration_failed), и не меняется при повторе с тем же Idempotency-Key. По нему GET /orders/{id} показывает исход, а POST /market/lots с order_id выставляет купленный домен. У отказа до резерва денег номера нет — заказа не было.
Одна сумма: цена проверяется при приёме запроса (не выше max_price) и ещё раз в момент резерва денег. Выросла между проверками — покупки нет: 409 price_changed, в error.price — новая цена, в error.confirmed_price — проверенная при приёме, ничего не списано. Новая цена не выше той, что подтвердил пользователь, — повторите с тем же Idempotency-Key; выше — сначала переспросите пользователя. Снизилась — списывается меньшая. price в ответах, сумма заказа и трата дневного лимита — ровно то, что зарезервировано или списано.
registration — как зарегистрирован домен: mode live (у настоящего регистратора) или sandbox (тестовый режим площадки: регистрация — симуляция, у регистратора домена нет, хотя деньги списаны с баланса), years — срок (через API всегда 1), real — true только для live. При real: false не сообщайте пользователю, что домен куплен: такой домен нельзя выставить на продажу (409 domain_not_real).
Ответ потерялся (таймаут, обрыв) и номер заказа неизвестен — спросите GET /domains/register/{Idempotency-Key}: он ничего не покупает и не списывает.
Повтор после отказа до регистратора или после 404 not_started — новая попытка: цена и лимиты трат проверяются заново. Idempotency-Key с первой попытки привязан к домену: тот же ключ с другим доменом — 422 idempotency_key_reused.
Idempotency-Key действует в пределах аккаунта: повтор с другим API-ключом того же аккаунта (например, после смены ключа) вернёт ту же покупку с пометкой other_api_key: true, а не купит второй раз.
{
"ok": true,
"status": "pending",
"price": "12.99",
"currency": "USD",
"domain_name": "example.com",
"message": "The registrar is still processing the order. Check GET /api/v1/domains/example.com in a few minutes.",
"registration": {"mode": "live", "years": 1, "real": true},
"order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "pending"}
}
409 Conflict
{
"ok": false,
"error": {
"code": "registration_failed",
"message": "Registration failed, the money was returned to your balance.",
"domain": "example.com",
"refunded": true
},
"registration": {"mode": "live", "years": 1, "real": true},
"order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "failed"}
}
409 Conflict — цена выросла между проверками
{
"ok": false,
"error": {
"code": "price_changed",
"message": "The price changed: $13.99 instead of the confirmed $12.99. Nothing was charged — confirm the new price and buy again.",
"domain": "example.com",
"price": "13.99",
"confirmed_price": "12.99",
"charged": false,
"max_price": "15.00"
}
}
201 Created — тестовый режим (sandbox), домен не настоящий (поля домена сокращены)
{
"ok": true,
"status": "registered",
"price": "12.99",
"currency": "USD",
"registration": {
"mode": "sandbox",
"years": 1,
"real": false,
"note": "Test mode (sandbox): the domain was NOT registered at the registrar — this is a simulated purchase. Do not tell the user the domain is theirs and do not list it for sale."
},
"order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "registered"},
"domain": {
"id": "svc_9d3a1f0b2c4e6a8b0d1f3e5a",
"domain": "example.com",
"status": "active",
"registration": {"mode": "sandbox", "years": 1, "real": false, "note": "Test mode (sandbox): the domain was NOT registered at the registrar — …"}
}
}
GET/domains/register/{idempotency_key}
Чем кончилась покупка (по Idempotency-Key)
Сверка после потерянного ответа: ответ на POST /domains/register не дошёл, и номер заказа неизвестен — а Idempotency-Key вы знали ещё до отправки. Только чтение: этот запрос ничего не покупает, не списывает и не ходит к регистратору.
Право: read
Параметр
Тип
Обязателен
Описание
idempotency_key
path
да
Тот же Idempotency-Key, что был в заголовке покупки. Ищется во всём аккаунте: покупку, сделанную другим API-ключом аккаунта (например, до смены ключа), сверка тоже найдёт — с пометкой other_api_key: true.
200 — заказ есть: order — тот же объект, что в GET /orders/{id} (status pending, registered или failed, refunded, списанная сумма price, registration, domain_service, listing). Пока status: pending — заголовок Retry-After.
202 in_progress — покупка с этим ключом ещё выполняется: спросите снова через Retry-After секунд и новую покупку не начинайте.
404 not_started — до регистратора покупка не дошла (или ей отказали до резерва денег): ничего не списано. Отправьте POST /domains/register с ТЕМ ЖЕ Idempotency-Key — если первая попытка всё-таки успела, повтор вернёт её итог, а не купит второй раз.
{
"ok": true,
"status": "in_progress",
"idempotency_key": "buy-example-com-20261001",
"retry_after": 5,
"message": "A purchase with this key is still running — ask again in a few seconds. Do not start a new purchase."
}
404 Not Found
{
"ok": false,
"error": {
"code": "not_started",
"message": "The purchase with this key never reached the registrar: nothing was charged and no domain was ordered. Send POST /api/v1/domains/register with the SAME Idempotency-Key — it will not create a second purchase.",
"idempotency_key": "buy-example-com-20261001",
"charged": false
}
}
GET/domains
Мои домены
Все домены аккаунта постранично. can_list — можно ли выставить домен на продажу прямо сейчас, list_blocked_reason — почему нельзя, listing — текущий лот, если домен уже продаётся.
Статус, срок оплаты, NS-серверы и текущий лот одного домена. Этим же запросом дожидаются выдачи домена после ответа 202.
Право: read
Параметр
Тип
Обязателен
Описание
domain
path
да
Имя домена в адресе.
Пока домен после ответа 202 не выдан, ответ — 200 с "domain": null и status: pending. Регистрация не удалась — status: failed и refunded: true, деньги вернулись на баланс. 404 — нет ни домена, ни попытки его купить.
registration.real: false — домен куплен в тестовом режиме (sandbox): у регистратора его нет.
{
"ok": true,
"domain": null,
"domain_name": "example.com",
"status": "pending",
"message": "The registrar is still processing the order. Check GET /api/v1/domains/example.com in a few minutes.",
"registration": {"mode": "live", "years": 1, "real": true},
"order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "pending"}
}
200 OK — регистрация не удалась
{
"ok": true,
"domain": null,
"domain_name": "example.com",
"status": "failed",
"refunded": true,
"message": "Registration failed, the money was returned to your balance.",
"registration": {"mode": "live", "years": 1, "real": true},
"order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "failed"}
}
GET/orders
Мои заказы
Покупки доменов, дошедшие до регистратора, новые сверху (последние 5000): через API и на сайте. Каждый элемент items — объект заказа, как в GET /orders/{id}.
Право: read
Параметр
Тип
Обязателен
Описание
status
string
нет
Фильтр: pending (регистратор ещё работает), registered (домен куплен), failed (не удалось, деньги вернулись).
Исход покупки по номеру заказа из ответа POST /domains/register: status pending, registered или failed. Здесь же — услуга домена, текущий лот и подсказка next: что делать дальше.
Право: read
Параметр
Тип
Обязателен
Описание
id
path
да
Номер заказа (order.id, dq_…).
status: pending — регистратор ещё работает, деньги в резерве: спрашивайте снова через Retry-After секунд (заголовок есть у таких ответов). registered — домен куплен. failed — регистрация не удалась, деньги вернулись на баланс (refunded: true).
domain_service — домен в вашем аккаунте; null, пока заказ не registered или если домен уже не ваш (продан, передан, удалён). listing — ваш живой лот с этим доменом. can_list и list_blocked_reason — можно ли выставить домен сейчас и почему нельзя.
next — следующий шаг: wait (подождать и спросить снова), list_on_market (выставить: метод, путь и тело запроса готовы), manage_listing (домен уже продаётся) или null — делать нечего.
Чужой или неизвестный номер — 404 order_not_found: API не подтверждает существование чужих заказов. Цена — то, что списано с вас (или зарезервировано), без себестоимости.
registration — как зарегистрирован домен (mode live или sandbox, years, real), как в ответе покупки. У sandbox-заказа can_list: false — тестовый домен выставить нельзя.
{
"ok": true,
"order": {
"id": "dq_5adc8ffc18cbcba5c488dd9e",
"type": "domain_register",
"domain": "example.com",
"domain_display": "example.com",
"status": "pending",
"refunded": false,
"price": "12.99",
"currency": "USD",
"registration": {"mode": "live", "years": 1, "real": true},
"created_at": "2026-10-01 09:14:40",
"updated_at": "2026-10-01 09:14:40",
"domain_service": null,
"listing": null,
"can_list": false,
"list_blocked_reason": null,
"next": {
"action": "wait",
"method": "GET",
"path": "/api/v1/orders/dq_5adc8ffc18cbcba5c488dd9e",
"retry_after": 60,
"message": "The registrar is still processing the order: ask again in a minute."
}
}
}
GET/market/lots
Мои лоты
Ваши лоты в магазине доменов, новые сверху (последние 1000). Каждый элемент items — объект лота, как в ответе на выставление: с карточкой card и состоянием ИИ-описания ai.
Право: read
Параметр
Тип
Обязателен
Описание
status
string
нет
Фильтр: active (продаётся или забронирован), listed, reserved, sold, delisted, cancelled.
page
integer
нет
Номер страницы, с 1.
per_page
integer
нет
Размер страницы: по умолчанию 50, максимум 100.
status лота: for_sale — продаётся, reserved — покупатель оплачивает счёт, sold — продан, unavailable — снят с продажи. raw_status — точный статус: listed, reserved, sold, delisted (сняли вы), cancelled (снят системой: домен истёк или ушёл из аккаунта).
cancel_reason — почему лот снят системой (только у cancelled): expiring — домен скоро истекает, owner_changed — домен ушёл из аккаунта, service_missing или service_<статус> — услуги домена нет или она не активна. У остальных лотов — null. sandbox — домен куплен в тестовом режиме и у регистратора не существует.
Создаёт лот в магазине доменов. Домен должен быть в вашем аккаунте HQClouds, активным, оплаченным ещё минимум на 30 дн. и без идущих операций у регистратора.
Право: market:write
Параметр
Тип
Обязателен
Описание
domain
string
нет
Домен из вашего аккаунта. Передайте domain или order_id — одно из двух.
order_id
string
нет
Номер заказа из ответа на покупку (order.id): выставить купленный домен, не повторяя его имя. Заказ ещё pending — 409 order_pending с Retry-After, failed — 409 order_failed, домен уже не ваш — 409 domain_not_owned, чужой или неизвестный номер — 404 order_not_found. Домен из тестовой (sandbox) покупки — 409 domain_not_real: у регистратора его нет. Так и для лота, выставленного раньше: вместо already_listed — 409 domain_not_real, а сам лот снимается автоматически (cancel_reason: sandbox).
price
number
нет
Цена в USD: от $5 до $100,000. Не передали — цена по умолчанию, $50.
category
string
нет
Тематика — ключ из таблицы ниже. Не передали — определим по имени домена.
tags
array | string
нет
До 10 тегов: массив или строка через запятую. Тег — буквы, цифры, пробел или дефис, до 30 символов; «#» в начале снимаем, «_» заменяем на «-». Недопустимый тег — ошибка 422 invalid_field со списком rejected. Не передали — подставим по имени (cloud, pay, ai…).
headline
string
нет
Заголовок до 160 символов. Не передали — покупатель увидит автоописание на своём языке.
description
string
нет
Описание до 2000 символов. Не передали — автоописание на языке покупателя.
describe
string
нет
ИИ-описание: auto (по умолчанию) — если ИИ-описания включены, сделаем в фоне за несколько минут; ai — сгенерировать сразу, в этом же запросе: обычно 5–30 секунд, не дольше ~45 секунд (ставьте таймаут клиента 60 секунд). Сбой, лимит или выключенный ИИ не мешают выставлению: лот создаётся, в ai будет status: failed и код причины.
metadata
object
нет
Ваши данные, например оценка домена из HQName: до 20 полей, ключ — латиница, цифры и _ (до 40 символов), значение — строка до 300 символов, число, true/false или null. Возвращаются в ответах точно такими, как пришли; нарушение правил — 422 invalid_field.
При продаже площадка удерживает комиссию 10% от цены, остальное сразу зачисляется на ваш баланс HQClouds.
Повтор для уже выставленного домена — 200 и тот же лот с already_listed: true, без изменений (менять — PATCH). Новый лот — 201. Ретрай скрипта ничего не сломает.
Достаточно передать domain или order_id: цена, тематика, теги и текст подставятся сами. card — карточка лота ровно такой, какой её видит покупатель на языке ответа (?lang= или Accept-Language): заголовок, описание, «подойдёт для», тематика, теги, ссылка и картинка превью.
card.text_source — откуда текст: seller (написали вы), ai (ИИ-описание) или rules (автоописание по имени). Ваши headline и description всегда главнее ИИ: ИИ заполняет только пустые поля. headline и description на верхнем уровне — то, что написали вы (null — автотекст).
card.pronunciation — как читается имя: ipa, en (английская запись, ударный слог заглавными), ru (русская транскрипция); source: ai — от ИИ, rules — примерно по правилам чтения (approx: true, без IPA и ударения; запись, совпадающая с самим именем, — пустая строка, а у имён с цифрами и очень длинных pronunciation — null). card.meaning — части имени и их происхождение, card.translations — смысл имени на языках en, ru, de, es, fr, it, pt, zh, ja (у придуманных имён пусто), card.language_notes — замечания о звучании в крупных языках (обычно пусто).
card.score — «Оценка HQ» 0–100: баллы за само имя по правилам HQClouds (длина, звучание, запоминаемость, запись, зону, смысл — с учётом card.meaning) с подсказкой к каждой части. Это не цена и не оценка стоимости. Те же поля без подписей есть и на верхнем уровне лота.
ai — состояние ИИ-описания, всегда один из четырёх статусов: ready (готово, languages — на каких языках), queued (сделаем в фоне; с code: ai_in_progress — уже генерируется другим запросом), disabled (само не появится, reason — почему: ai_off — ИИ-описания на площадке выключены, auto_off — фоновая генерация выключена, закажите через /describe, lot_not_active — лот не продаётся), failed (не получилось — code и reason говорят почему). Пока ИИ-текста нет, покупатель видит автоописание по правилам.
Ответ на describe: "ai" не дошёл (таймаут, 502 или 504 от прокси) — лот уже создан: смотрите GET /market/lots/{domain}, ai.status станет ready, когда текст будет готов. Повтор запроса тоже безопасен: вернёт тот же лот, а пока генерация идёт, второй не будет.
Три статуса — независимы: order.status — покупка, lot.status — публикация, ai.status — ИИ-описание. Сбой ИИ не отменяет публикацию (лот создан — 201, а ai.status: failed) и никогда не запускает покупку: этот запрос денег не двигает.
{
"ok": false,
"error": {
"code": "order_pending",
"message": "The registrar is still processing the order — the domain can be listed once it is registered. Retry in a minute.",
"retry_after": 60
},
"order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "pending"}
}
GET/market/lots/{domain}
Один лот
Лот по имени домена или по id лота (lot_…). Если домен выставлялся несколько раз, вернётся живой лот, иначе последний.
{
"ok": true,
"lot": {
"id": "lot_1a2b3c4d5e6f7a8b9c0d1e2f",
"domain": "example.com",
"domain_display": "example.com",
"sld": "example",
"tld": ".com",
"length": 7,
"has_digits": false,
"has_hyphen": false,
"price": "249.00",
"currency": "USD",
"status": "for_sale",
"category": "tech",
"category_label": "Technology",
"tags": ["short", "brandable"],
"headline": null,
"description": null,
"headline_text": "A short, crisp name for a tech product",
"description_text": "Seven letters and three syllables: easy to say, spell and remember. The .com ending is what customers type first. A good fit for a SaaS product, a developer tool or an AI assistant.",
"text_auto": true,
"text_source": "ai",
"use_cases": ["SaaS startup", "developer tool", "AI assistant"],
"paid_until": "2027-10-01",
"listed_at": "2026-10-01",
"views": 0,
"raw_status": "listed",
"source": "api",
"reserved_until": null,
"sold_at": null,
"delisted_at": null,
"cancel_reason": null,
"metadata": {"score": 87, "source": "hqname"},
"url": "https://hqclouds.com/market/example.com?lang=en",
"card": {
"domain": "example.com",
"price": "249.00",
"currency": "USD",
"headline": "A short, crisp name for a tech product",
"description": "Seven letters and three syllables: easy to say, spell and remember. The .com ending is what customers type first. A good fit for a SaaS product, a developer tool or an AI assistant.",
"use_cases": ["SaaS startup", "developer tool", "AI assistant"],
"category": "tech",
"category_label": "Technology",
"tags": ["short", "brandable"],
"text_source": "ai",
"ai_languages": ["en", "ru"],
"language": "en",
"url": "https://hqclouds.com/market/example.com?lang=en",
"og_image": "https://hqclouds.com/market/example.com/og?lang=en",
"pronunciation": {"ipa": "/ɪɡˈzɑːm.pəl/", "en": "ig-ZAHM-pul", "ru": "иг-ЗАМ-пл", "latin": null, "source": "ai", "approx": false},
"meaning": [{"part": "example", "lang_ru": "английский", "lang_en": "English", "ru": "пример", "en": "example"}],
"translations": [{"lang": "ru", "text": "пример"}, {"lang": "de", "text": "Beispiel"}, {"lang": "ja", "text": "例"}],
"language_notes": [],
"score": {
"total": 95, "max": 100, "grade": "excellent", "grade_label": "excellent", "version": 2,
"parts": [
{"key": "length", "score": 20, "max": 20, "hint": "length_sweet", "label": "Length", "hint_text": "5 to 8 characters — a handy length for a brand."},
{"key": "sound", "score": 16, "max": 20, "hint": "sound_cluster", "label": "Sound", "hint_text": "A consonant cluster makes it harder to say."}
]
}
},
"ai": {"status": "ready", "languages": ["en", "ru"], "generated_at": "2026-10-01 12:00:41"}
},
"ai": {"status": "ready", "languages": ["en", "ru"], "generated_at": "2026-10-01 12:00:41"}
}
PATCH/market/lots/{domain}
Изменить лот
Передайте только те поля, которые меняете: price, category, tags, headline, description, metadata. null или пустая строка очищает поле (кроме цены): тематика и теги снова определятся автоматически, вместо заголовка и описания снова будет автоописание (ИИ или по правилам).
Право: market:write
Параметр
Тип
Обязателен
Описание
domain
path
да
Имя домена или id лота.
price
number
нет
Новая цена в USD.
category, tags
нет
Как при выставлении; null или "" — определить автоматически.
headline, description
string | null
нет
Ваш текст — он всегда главнее ИИ. null или "" — вернуть автоописание.
metadata
object
нет
Заменяет ваши metadata целиком, null или {} — очищает. Правила — как при выставлении.
describe
string
нет
ai — после сохранения сразу сделать ИИ-описание, если его ещё нет; если эта же правка сменила тематику или теги — написать его заново под новую тему. Перегенерировать без правок — POST …/describe с force. Можно передать и без других полей.
Пока покупатель оплачивает домен (reserved), лот нельзя ни изменить, ни снять, ни перегенерировать — 409 lot_reserved; после окончания брони можно. Снятый или проданный лот — 409 lot_not_active.
Ответ — лот целиком, с обновлённой карточкой card: по ней видно, что теперь покажет покупатель.
{
"ok": true,
"lot": {
"id": "lot_1a2b3c4d5e6f7a8b9c0d1e2f",
"domain": "example.com",
"price": "199.00",
"status": "for_sale",
"raw_status": "listed",
"headline": "Short brandable .com",
"description": null,
"url": "https://hqclouds.com/market/example.com?lang=en",
"card": {
"headline": "Short brandable .com",
"description": "Seven letters and three syllables: easy to say, spell and remember. The .com ending is what customers type first. A good fit for a SaaS product, a developer tool or an AI assistant.",
"text_source": "ai"
}
},
"ai": {"status": "ready", "languages": ["en", "ru"], "generated_at": "2026-10-01 12:00:41"}
}
POST/market/lots/{domain}/describe
ИИ-описание лота
Генерирует ИИ-описание лота сейчас, в этом же запросе: заголовок, описание и «подойдёт для» на русском и английском, а также уточняет автоматические тематику и теги. Обычно 5–30 секунд, не дольше ~45 секунд: ставьте таймаут клиента 60 секунд. В этом запросе модель отвечает один раз: негодный ответ — 502 ai_failed (reason: rejected), повторите позже. Сама площадка повторяет (при включённой автогенерации) только для лота, у которого ИИ-текста ещё нет; неудачная перегенерация (force) оставляет прежний ИИ-текст — её повторяйте сами.
Право: market:write
Параметр
Тип
Обязателен
Описание
domain
path
да
Имя домена или id лота.
force
boolean
нет
true — сгенерировать заново, даже если ИИ-описание уже есть. Без force готовое описание возвращается сразу (cached: true) и лимит генераций не тратится.
Ваши headline и description ИИ не перезаписывает: они всегда главнее, ИИ-текст покажется только в пустых полях. Выбранные вами тематику и теги ИИ тоже не трогает.
Отказы: 503 ai_unavailable — ИИ-описания выключены; 429 ai_rate_limited — лимит генераций или уже идут 2 генерации ваших лотов сразу (reason: user_concurrency), повторите через Retry-After секунд; 409 ai_in_progress — этот лот уже генерируется другим запросом; 502 ai_failed — модель не дала годного текста. Во всех случаях лот остаётся в продаже с прежним текстом: ИИ-описанием, если оно уже было, иначе автоописанием по правилам.
Только для лотов в продаже: снятый или проданный лот — 409 lot_not_active, забронированный покупателем — 409 lot_reserved.
Ответ не дошёл (таймаут) — не заказывайте заново: смотрите GET /market/lots/{domain}, ai.status станет ready, когда текст будет готов. Повтор, пока первая генерация идёт, ответит 409 ai_in_progress и денег на вторую не потратит.
brand Брендtech Технологииai ИИbusiness Бизнесfinance Финансыcrypto Криптоecommerce Магазинcreative Творчествоsocial Сообществоhealth Здоровьеeducation Образованиеtravel Путешествияfood Едаrealestate Недвижимостьfun Хобби и игры
Сценарий: купить и сразу выставить
Весь путь одним скриптом — так работает связка с HQName: нашли хорошее имя, купили его с баланса, получили номер заказа и по нему сразу выставили домен в магазин HQClouds с ИИ-описанием. Дальше — правки и снятие тем же лотом.
bash
export HQC_TOKEN="hqc_xxxxxxxx_..."
DOMAIN="example.com"
# Ключ покупки: один на покупку. Скрипт его печатает — перезапуск с KEY=<тот же> продолжит ту же покупку, а не начнёт новую.
KEY="${KEY:-$(uuidgen)}"
echo "Idempotency-Key: $KEY" >&2
# 1. Купить домен. В ответе — номер заказа order.id. Сбой сети, 5xx, busy или 429 — повтор с тем же KEY: деньги не спишутся дважды. Другой отказ (домен занят, баланс, max_price) — выход.
# price_changed — цена выросла между проверками, ничего не списано: переспросите пользователя. Узнать итог без покупки — GET /domains/register/$KEY.
for TRY in 1 2 3 4 5; do
RESP=$(curl -s -X POST https://hqclouds.com/api/v1/domains/register \
-H "Authorization: Bearer $HQC_TOKEN" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: $KEY" \
-d "{\"domain\":\"$DOMAIN\",\"max_price\":15}")
ORDER=$(echo "$RESP" | jq -r '.order.id // empty' 2>/dev/null)
[ -n "$ORDER" ] && break
CODE=$(echo "$RESP" | jq -r '.error.code // empty' 2>/dev/null)
case "$CODE" in ""|busy|rate_limited|internal_error) sleep 15 ;; *) echo "$CODE" >&2; exit 1 ;; esac
done
[ -n "$ORDER" ] || { echo "no order, KEY=$KEY" >&2; exit 1; }
# 2. Ждём итога: GET /orders/{id} раз в минуту, пока status не станет registered или failed. Сбой сети, 429 и 5xx — следующая попытка; другая ошибка (токен отозван, нет права, заказ не найден) — выход.
while :; do
RESP=$(curl -s https://hqclouds.com/api/v1/orders/$ORDER \
-H "Authorization: Bearer $HQC_TOKEN")
STATUS=$(echo "$RESP" | jq -r '.order.status // empty' 2>/dev/null)
case "$STATUS" in registered|failed) break ;; esac
CODE=$(echo "$RESP" | jq -r 'if .ok == false then .error.code else empty end' 2>/dev/null)
case "$CODE" in ""|rate_limited|internal_error) sleep 60 ;; *) echo "$CODE" >&2; exit 1 ;; esac
done
[ "$STATUS" = "registered" ] || { echo "$DOMAIN: $STATUS" >&2; exit 1; }
# Тестовый режим площадки (sandbox): домен не настоящий — не сообщать пользователю о покупке и не выставлять.
[ "$(echo "$RESP" | jq -r '.order.registration.real')" = "true" ] || { echo "$DOMAIN: sandbox" >&2; exit 1; }
# 3. Выставить по номеру заказа: своя цена и ИИ-описание сразу. Повтор вернёт тот же лот (already_listed).
curl -s --max-time 60 -X POST https://hqclouds.com/api/v1/market/lots \
-H "Authorization: Bearer $HQC_TOKEN" \
-H "Content-Type: application/json" \
-d "{\"order_id\":\"$ORDER\",\"price\":\"249\",\"describe\":\"ai\"}" | jq '.lot.card, .ai'
# 4. Поправить: новая цена и свой заголовок (текст продавца главнее ИИ; null вернёт автоописание).
curl -s -X PATCH https://hqclouds.com/api/v1/market/lots/$DOMAIN \
-H "Authorization: Bearer $HQC_TOKEN" \
-H "Content-Type: application/json" \
-d '{"price":"199","headline":"Short brandable .com"}' | jq '.lot.card'
# 5. Перегенерировать ИИ-описание (force — даже если оно уже есть).
curl -s --max-time 60 -X POST https://hqclouds.com/api/v1/market/lots/$DOMAIN/describe \
-H "Authorization: Bearer $HQC_TOKEN" \
-H "Content-Type: application/json" \
-d '{"force":true}' | jq '.ai'
# 6. Снять с продажи, если передумали.
curl -s -X DELETE https://hqclouds.com/api/v1/market/lots/$DOMAIN \
-H "Authorization: Bearer $HQC_TOKEN" | jq '.lot.raw_status'
Номер заказа (dq_…) — ключ ко всему пути: GET /orders/{id} показывает исход покупки, домен и следующий шаг, POST /market/lots с order_id выставляет домен без повтора его имени. Список всех заказов — GET /orders.
Каждый шаг можно безопасно повторить: покупка — с тем же Idempotency-Key (скрипт печатает KEY: запустите его снова с KEY=… — продолжится та же покупка, а не начнётся новая), выставление вернёт тот же лот с already_listed: true, describe без force отдаст готовый текст, повторное снятие вернёт уже снятый лот.
Только что купленный домен оплачен на год — условие «оплачен ещё минимум на 30 дн.» выполняется сразу.
describe: "ai" ждёт ответа модели: обычно 5–30 секунд, не дольше ~45 секунд (в скрипте — --max-time 60). Если ИИ недоступен или упёрся в лимит, лот всё равно выставлен — в ai будет status: failed с кодом, а покупатель видит автоописание. Без describe ИИ-описание появится само в течение нескольких минут, если оно включено на площадке.
Для покупки нужен ключ с правом domains:register, для выставления — с правом market:write. Можно один ключ с обоими правами.
Вопросы
Сколько стоит API?
API бесплатно. Домены через API стоят столько же, сколько на сайте, деньги списываются с баланса HQClouds.
Что делать, если запрос на покупку оборвался по таймауту?
Спросите, чем кончилась покупка: GET /api/v1/domains/register/{Idempotency-Key} — ничего не покупает и не списывает. Заказ есть — в ответе его статус и номер; «не начиналась» (404 not_started) — повторите POST с тем же Idempotency-Key. Повтор POST с тем же ключом всегда безопасен: если покупка уже прошла, API вернёт её результат и не спишет деньги второй раз.
Можно ли купить премиум-домен через API?
Нет. Цена премиум-домена может быть в сотни раз выше обычной, поэтому такие домены покупаются только вручную в кабинете.
Как выставить домен на продажу сразу после покупки?
Ответ на покупку содержит номер заказа order.id. Дождитесь status: registered в GET /api/v1/orders/{id} и отправьте POST /api/v1/market/lots с order_id — цену, тематику и описание можно не передавать, ИИ-описание закажите полем describe: "ai".
Как отозвать токен?
В кабинете, в разделе «API»: отзыв действует мгновенно. Создайте новый ключ и замените токен в своей программе.
Готовы начать?
Создайте ключ в кабинете — это бесплатно и займёт минуту.