API v1 · REST · JSON

API для разработчиков

Проверяйте и покупайте домены, выставляйте их на продажу и смотрите историю продаж из своего кода — тем же движком и по тем же ценам, что на сайте.

Базовый адрес
URL
https://hqclouds.com/api/v1

Что умеет API

Проверка доменов

Свободен ли домен, цена регистрации и продления.

Покупка с баланса

Регистрация тем же движком и по тем же ценам, что на сайте, с лимитом трат на ключ.

Мои домены

Список доменов, сроки оплаты, NS и можно ли выставить на продажу.

Продажа доменов

Выставляйте домены, меняйте цену и описание, снимайте с продажи.

Купил — выставил

Номер заказа из ответа на покупку сразу выставляет домен в магазин, а ИИ пишет карточку на русском и английском.

История продаж

Продажи, комиссия площадки и сколько зачислено на баланс.

Поиск по магазину

Публичный поиск лотов с фильтрами — без токена.

API работает с сервера: ваш скрипт, бот или сервис (например, HQName) обращается к HQClouds по HTTPS с токеном из кабинета. Все суммы — в USD, деньги списываются с баланса HQClouds.

Быстрый старт

  1. Войдите или зарегистрируйтесь в HQClouds. Если собираетесь покупать домены — пополните баланс и один раз заполните контакты владельца домена (WHOIS): контакты WHOIS.
  2. В кабинете откройте раздел «API» и создайте ключ: название, права и дневной лимит трат.
  3. Скопируйте токен — он показывается только один раз. Сохраните его в переменной окружения или менеджере секретов.
  4. Сделайте первый запрос:
bash
export HQC_TOKEN="hqc_xxxxxxxx_..."

curl -s https://hqclouds.com/api/v1/me \
  -H "Authorization: Bearer $HQC_TOKEN"

Получить API-токен

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

Каждый запрос (кроме публичного поиска по магазину) передаёт токен в заголовке Authorization:

http
Authorization: Bearer hqc_xxxxxxxx_xxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxxx
  • Токен показывается один раз при создании. Мы храним только его хэш — восстановить токен нельзя, только выпустить новый.
  • Не вставляйте токен в код сайта или мобильного приложения: 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 ключей в час.
HTTPcodeЧто значит
HTTP 401unauthorized, invalid_tokenТокена нет, он неверный, отозван или истёк. Считается неудачным входом.
HTTP 403ip_not_allowedТокен верный, но у ключа есть список разрешённых IP, а запрос пришёл с другого адреса. Адрес, который увидел сервер, — в сообщении и в поле ip.
HTTP 403scope_requiredУ ключа нет нужного права — выпустите ключ с ним.
HTTP 429too_many_auth_failuresС вашего IP слишком много неудачных входов: больше 30 за минуту или 300 за час. До конца окна запросы с этого IP не принимаются, время — в Retry-After.
HTTP 429rate_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 с тем же ключом). Этот запрос только читает: ничего не покупает и не списывает.
http
-H "Idempotency-Key: 3f6d1c52-8a4e-4b0f-9e21-7c5d9a0b4e18"

Ответы и ошибки

Все ответы — 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."
  }
}
HTTPcodeЧто значит
HTTP 200already_listedНе ошибка: домен уже выставлен — ответ 200 с тем же лотом и already_listed: true, ничего не изменено.
HTTP 400invalid_jsonТело запроса — не JSON-объект.
HTTP 400bad_requestНекорректный запрос: например, параметр в адресе неверного вида.
HTTP 401unauthorizedНет заголовка Authorization: Bearer.
HTTP 401invalid_tokenТокен неверный, отозван или истёк.
HTTP 402insufficient_balanceНе хватает денег на балансе — пополните его в кабинете.
HTTP 403ip_not_allowedУ ключа есть список разрешённых IP, а запрос пришёл с другого адреса (адрес — в поле ip).
HTTP 403scope_requiredУ ключа нет нужного права.
HTTP 403no_spend_limitУ ключа нет дневного лимита трат — покупать им нельзя.
HTTP 404not_foundНет такого адреса API, домена или лота — или он не ваш.
HTTP 404order_not_foundНет такого заказа — или он не ваш.
HTTP 404not_startedСверка по Idempotency-Key: покупка с этим ключом до регистратора не дошла, ничего не списано — повторите POST с тем же ключом.
HTTP 405method_not_allowedЭтот адрес не поддерживает такой метод.
HTTP 409registration_failedРегистратор отказал уже после резерва — деньги вернулись на баланс (refunded: true).
HTTP 409not_availableДомен занят или его доступность не удалось подтвердить — деньги не списаны. Повтор с тем же Idempotency-Key проверит домен заново.
HTTP 409no_contactНе заполнены контакты владельца домена (WHOIS) — заполните их один раз в кабинете.
HTTP 409price_above_maxИтоговая цена выше max_price — покупка не сделана.
HTTP 409price_changedЦена выросла между проверкой запроса и резервом денег — покупка не сделана, ничего не списано. Новая цена — в error.price, проверенная — в error.confirmed_price.
HTTP 409premium_not_allowedПремиум-домен: только вручную в кабинете.
HTTP 409…Прочие отказы покупки до регистратора — деньги не списаны, причина в message.
HTTP 409order_pendingРегистратор ещё обрабатывает заказ — выставить домен можно после регистрации. Повторите через Retry-After секунд.
HTTP 409order_failedРегистрация по заказу не удалась, деньги вернулись — выставлять нечего.
HTTP 409domain_not_ownedДомена из заказа больше нет в вашем аккаунте: продан, передан или удалён.
HTTP 409domain_not_realДомен куплен в тестовом режиме (sandbox) и у регистратора не существует — выставить его на продажу нельзя.
HTTP 409lot_not_activeЛот снят или продан — менять его и заказывать ИИ-описание нельзя.
HTTP 409lot_reservedПокупатель сейчас оплачивает домен — до конца брони лот нельзя менять, снимать и перегенерировать.
HTTP 409ai_in_progressИИ-описание этого лота уже генерируется другим запросом — проверьте лот через Retry-After секунд.
HTTP 413payload_too_largeТело запроса больше 64 КБ.
HTTP 422validation_failedОшибка в данных (цена, тематика, домен нельзя выставить и т. п.) — подробности в message.
HTTP 422domain_required, invalid_domain, invalid_field, idempotency_key_requiredНе хватает параметра или он в неверном формате.
HTTP 422invalid_idempotency_keyIdempotency-Key длиннее 100 символов или с недопустимыми символами — ключ не обрезается, а отклоняется.
HTTP 422idempotency_key_reusedЭтот Idempotency-Key уже использован для покупки другого домена.
HTTP 422invalid_max_pricemax_price — не обычное число (например, 1e3, true или текст).
HTTP 422years_unsupportedЧерез API доступна регистрация только на 1 год.
HTTP 422quote_failedНе удалось получить цену домена — подробности в message.
HTTP 422invalid_statusНеизвестное значение фильтра status у списка лотов или заказов.
HTTP 422nothing_to_updateВ PATCH не передано ни одного поля для изменения.
HTTP 429rate_limitedПревышен лимит запросов в минуту — подождите Retry-After секунд.
HTTP 429too_many_auth_failuresС одного IP больше 30 неудачных входов за минуту или 300 за час (без токена, с неверным токеном, не с разрешённого IP) — запросы с этого IP не принимаются до конца окна, время — в Retry-After.
HTTP 429daily_limit, hourly_limitИсчерпан дневной лимит трат ключа или лимит покупок в час.
HTTP 429busyСейчас идёт другая покупка — повторите через несколько секунд с тем же Idempotency-Key.
HTTP 429ai_rate_limitedЛимит ИИ-генераций или слишком много генераций сразу — повторите через Retry-After секунд. Лот при этом остаётся в продаже.
HTTP 500internal_errorСбой на нашей стороне. Покупку повторяйте с тем же Idempotency-Key.
HTTP 502ai_failedМодель не дала годного описания — лот остаётся с прежним текстом (ИИ-описанием, если оно было, иначе автоописанием по правилам), повторите позже.
HTTP 503api_disabled, market_disabledAPI или магазин доменов временно выключены.
HTTP 503ai_unavailableИИ-описания сейчас выключены — покупатели видят описание по правилам.

Эндпоинты

Пути указаны относительно базового адреса https://hqclouds.com/api/v1.

GET /me

Аккаунт, баланс и ключ

Кто владелец токена, сколько денег на балансе, какие права у ключа и сколько из дневного лимита уже потрачено. Удобно проверить токен перед работой.

Право: read

Запрос

bash
curl -s https://hqclouds.com/api/v1/me \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK
{
  "ok": true,
  "user": {"id": "6f1c2a9e-3b7d-4e2a-9c51-8d0f2b7a4e13", "email": "you@example.com"},
  "balance": {"amount": "120.50", "currency": "USD"},
  "key": {
    "id": "key_4b2f9a1c7d3e5f60a1b2c3d4",
    "name": "HQName",
    "scopes": ["read", "domains:register", "market:write"],
    "daily_spend_limit": "100.00",
    "spent_24h": "12.99",
    "rate_limit_per_minute": 60,
    "expires_at": null,
    "ip_allowlist": ["203.0.113.7"]
  }
}
GET /domains/check

Проверить домен

Свободен ли домен и сколько стоят регистрация и продление. Ничего не покупает. Если домен продаётся в магазине HQClouds, в for_sale будут цена и ссылка.

Право: read

Параметр Тип Обязателен Описание
domain string да Имя домена, например example.com. Домены на кириллице принимаются как есть.
  • state: available — свободен, taken — занят, premium — премиум-домен (через API не продаётся), for_sale — продаётся в магазине HQClouds, unsupported_tld — зону мы не регистрируем, unknown — проверить не удалось, повторите позже.
  • Доступность — предварительная: окончательная проверка цены и наличия происходит в момент покупки.

Запрос

bash
curl -s "https://hqclouds.com/api/v1/domains/check?domain=example.com" \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK
{
  "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, а не купит второй раз.

Запрос

bash
curl -s -X POST https://hqclouds.com/api/v1/domains/register \
  -H "Authorization: Bearer $HQC_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: buy-example-com-20261001" \
  -d '{"domain":"example.com","max_price":15}'

Ответ

201 Created
{
  "ok": true,
  "status": "registered",
  "price": "12.99",
  "currency": "USD",
  "registration": {"mode": "live", "years": 1, "real": true},
  "order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "registered"},
  "domain": {
    "id": "svc_9d3a1f0b2c4e6a8b0d1f3e5a",
    "domain": "example.com",
    "status": "active",
    "expires_at": "2027-10-01 09:14:52",
    "auto_renew": true,
    "parked": false,
    "nameservers": [],
    "registration": {"mode": "live", "years": 1, "real": true},
    "listing": null
  }
}
202 Accepted
{
  "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 — если первая попытка всё-таки успела, повтор вернёт её итог, а не купит второй раз.

Запрос

bash
curl -s https://hqclouds.com/api/v1/domains/register/buy-example-com-20261001 \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK (поля заказа сокращены)
{
  "ok": true,
  "idempotency_key": "buy-example-com-20261001",
  "order": {
    "id": "dq_5adc8ffc18cbcba5c488dd9e",
    "type": "domain_register",
    "domain": "example.com",
    "status": "registered",
    "refunded": false,
    "price": "12.99",
    "currency": "USD",
    "registration": {"mode": "live", "years": 1, "real": true},
    "domain_service": {"id": "svc_9d3a1f0b2c4e6a8b0d1f3e5a", "domain": "example.com", "status": "active"},
    "listing": null,
    "can_list": true,
    "next": {"action": "list_on_market", "method": "POST", "path": "/api/v1/market/lots", "body": {"order_id": "dq_5adc8ffc18cbcba5c488dd9e"}}
  }
}
202 Accepted
{
  "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 — текущий лот, если домен уже продаётся.

Право: read

Параметр Тип Обязателен Описание
page integer нет Номер страницы, с 1.
per_page integer нет Размер страницы: по умолчанию 50, максимум 100.

Запрос

bash
curl -s "https://hqclouds.com/api/v1/domains?page=1&per_page=50" \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK
{
  "ok": true,
  "items": [
    {
      "id": "svc_9d3a1f0b2c4e6a8b0d1f3e5a",
      "domain": "example.com",
      "status": "active",
      "expires_at": "2027-10-01 09:14:52",
      "auto_renew": true,
      "parked": true,
      "nameservers": ["ns1.hqclouds.com", "ns2.hqclouds.com"],
      "registration": {"mode": "live", "years": 1, "real": true},
      "listing": null,
      "can_list": true,
      "list_blocked_reason": null
    }
  ],
  "total": 1,
  "page": 1,
  "pages": 1,
  "per_page": 50
}
GET /domains/{domain}

Один домен

Статус, срок оплаты, NS-серверы и текущий лот одного домена. Этим же запросом дожидаются выдачи домена после ответа 202.

Право: read

Параметр Тип Обязателен Описание
domain path да Имя домена в адресе.
  • Пока домен после ответа 202 не выдан, ответ — 200 с "domain": null и status: pending. Регистрация не удалась — status: failed и refunded: true, деньги вернулись на баланс. 404 — нет ни домена, ни попытки его купить.
  • registration.real: false — домен куплен в тестовом режиме (sandbox): у регистратора его нет.

Запрос

bash
curl -s https://hqclouds.com/api/v1/domains/example.com \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK
{
  "ok": true,
  "domain": {
    "id": "svc_9d3a1f0b2c4e6a8b0d1f3e5a",
    "domain": "example.com",
    "status": "active",
    "expires_at": "2027-10-01 09:14:52",
    "auto_renew": true,
    "parked": false,
    "nameservers": [],
    "registration": {"mode": "live", "years": 1, "real": true},
    "listing": {
      "id": "lot_1a2b3c4d5e6f7a8b9c0d1e2f",
      "price": "249.00",
      "status": "listed",
      "url": "https://hqclouds.com/market/example.com?lang=en"
    }
  }
}
200 OK — регистрация ещё идёт
{
  "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 (не удалось, деньги вернулись).
page integer нет Номер страницы, с 1.
per_page integer нет Размер страницы: по умолчанию 50, максимум 100.

Запрос

bash
curl -s "https://hqclouds.com/api/v1/orders?status=registered" \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK (поля заказа сокращены)
{
  "ok": true,
  "items": [
    {
      "id": "dq_5adc8ffc18cbcba5c488dd9e",
      "type": "domain_register",
      "domain": "example.com",
      "status": "registered",
      "refunded": false,
      "price": "12.99",
      "currency": "USD",
      "registration": {"mode": "live", "years": 1, "real": true},
      "can_list": true
    }
  ],
  "total": 1,
  "page": 1,
  "pages": 1,
  "per_page": 50
}
GET /orders/{id}

Один заказ

Исход покупки по номеру заказа из ответа 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 — тестовый домен выставить нельзя.

Запрос

bash
curl -s https://hqclouds.com/api/v1/orders/dq_5adc8ffc18cbcba5c488dd9e \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK
{
  "ok": true,
  "order": {
    "id": "dq_5adc8ffc18cbcba5c488dd9e",
    "type": "domain_register",
    "domain": "example.com",
    "domain_display": "example.com",
    "status": "registered",
    "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:52",
    "domain_service": {
      "id": "svc_9d3a1f0b2c4e6a8b0d1f3e5a",
      "domain": "example.com",
      "status": "active",
      "expires_at": "2027-10-01 09:14:52",
      "auto_renew": true,
      "parked": true,
      "nameservers": ["ns1.hqclouds.com", "ns2.hqclouds.com"],
      "registration": {"mode": "live", "years": 1, "real": true},
      "listing": null
    },
    "listing": null,
    "can_list": true,
    "list_blocked_reason": null,
    "next": {
      "action": "list_on_market",
      "method": "POST",
      "path": "/api/v1/market/lots",
      "body": {"order_id": "dq_5adc8ffc18cbcba5c488dd9e"},
      "message": "The domain is yours: list it for sale with POST /api/v1/market/lots and order_id."
    }
  }
}
200 OK — регистрация ещё идёт
{
  "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 — домен куплен в тестовом режиме и у регистратора не существует.

Запрос

bash
curl -s "https://hqclouds.com/api/v1/market/lots?status=active" \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK (поля лота сокращены)
{
  "ok": true,
  "items": [
    {
      "id": "lot_1a2b3c4d5e6f7a8b9c0d1e2f",
      "domain": "example.com",
      "price": "249.00",
      "status": "for_sale",
      "raw_status": "listed",
      "views": 12,
      "url": "https://hqclouds.com/market/example.com?lang=en",
      "ai": {"status": "queued", "attempts": 0}
    }
  ],
  "total": 1,
  "page": 1,
  "pages": 1,
  "per_page": 50
}
POST /market/lots

Выставить домен на продажу

Создаёт лот в магазине доменов. Домен должен быть в вашем аккаунте 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) и никогда не запускает покупку: этот запрос денег не двигает.

Запрос

bash
curl -s -X POST https://hqclouds.com/api/v1/market/lots \
  -H "Authorization: Bearer $HQC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"order_id":"dq_5adc8ffc18cbcba5c488dd9e","price":"249","category":"tech","tags":["short","brandable"],"describe":"ai","metadata":{"source":"hqname","score":87}}'

Ответ

201 Created
{
  "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", "cached": false}
  },
  "ai": {"status": "ready", "languages": ["en", "ru"], "generated_at": "2026-10-01 12:00:41", "cached": false},
  "order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "registered"}
}
201 Created — лот выставлен, ИИ-описание не вышло (поля лота сокращены)
{
  "ok": true,
  "lot": {
    "id": "lot_1a2b3c4d5e6f7a8b9c0d1e2f",
    "domain": "example.com",
    "price": "50.00",
    "currency": "USD",
    "status": "for_sale",
    "raw_status": "listed",
    "url": "https://hqclouds.com/market/example.com?lang=en",
    "card": {"headline": "Ready-made name for a mobile app", "text_source": "rules", "ai_languages": []},
    "ai": {"status": "failed", "code": "ai_failed", "reason": "error", "message": "Could not generate a description — try again later. The rule-based description is shown meanwhile."}
  },
  "ai": {"status": "failed", "code": "ai_failed", "reason": "error", "message": "Could not generate a description — try again later. The rule-based description is shown meanwhile."},
  "order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "registered"}
}
200 OK — домен уже выставлен (поля лота сокращены)
{
  "ok": true,
  "already_listed": true,
  "lot": {
    "id": "lot_1a2b3c4d5e6f7a8b9c0d1e2f",
    "domain": "example.com",
    "price": "249.00",
    "status": "for_sale",
    "raw_status": "listed",
    "url": "https://hqclouds.com/market/example.com?lang=en"
  },
  "ai": {"status": "ready", "languages": ["en", "ru"], "generated_at": "2026-10-01 12:00:41", "cached": true},
  "order": {"id": "dq_5adc8ffc18cbcba5c488dd9e", "status": "registered"}
}
409 Conflict
{
  "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_…). Если домен выставлялся несколько раз, вернётся живой лот, иначе последний.

Право: read

Параметр Тип Обязателен Описание
domain path да Имя домена или id лота.

Запрос

bash
curl -s https://hqclouds.com/api/v1/market/lots/example.com \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK
{
  "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: по ней видно, что теперь покажет покупатель.

Запрос

bash
curl -s -X PATCH https://hqclouds.com/api/v1/market/lots/example.com \
  -H "Authorization: Bearer $HQC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"price":"199.00","headline":"Short brandable .com","description":null}'

Ответ

200 OK (поля лота сокращены)
{
  "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 и денег на вторую не потратит.

Запрос

bash
curl -s -X POST https://hqclouds.com/api/v1/market/lots/example.com/describe \
  -H "Authorization: Bearer $HQC_TOKEN" \
  -H "Content-Type: application/json" \
  -d '{"force":true}'

Ответ

200 OK
{
  "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", "cached": false}
  },
  "ai": {"status": "ready", "languages": ["en", "ru"], "generated_at": "2026-10-01 12:00:41", "cached": false}
}
429 Too Many Requests
{
  "ok": false,
  "error": {
    "code": "ai_rate_limited",
    "message": "AI generation limit reached — try again later.",
    "reason": "user_hour_limit",
    "retry_after": 1200
  }
}
DELETE /market/lots/{domain}

Снять с продажи

Снимает лот с витрины. Повторный вызов безопасен: вернёт уже снятый лот.

Право: market:write

Параметр Тип Обязателен Описание
domain path да Имя домена или id лота.
  • Пока покупатель оплачивает домен (reserved), снять лот нельзя — 409 lot_reserved; после окончания брони можно.

Запрос

bash
curl -s -X DELETE https://hqclouds.com/api/v1/market/lots/example.com \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK (поля лота сокращены)
{
  "ok": true,
  "lot": {
    "id": "lot_1a2b3c4d5e6f7a8b9c0d1e2f",
    "domain": "example.com",
    "status": "unavailable",
    "raw_status": "delisted",
    "delisted_at": "2026-10-01 12:30:00",
    "url": "https://hqclouds.com/market/example.com?lang=en"
  }
}
GET /market/sales

История продаж

Завершённые продажи, новые сверху (последние 5000), и итоги по аккаунту.

Право: read

Параметр Тип Обязателен Описание
page integer нет Номер страницы, с 1.
per_page integer нет Размер страницы: по умолчанию 50, максимум 100.
  • stats: sold — продано доменов, revenue — сумма продаж, commission — комиссия площадки, proceeds — зачислено вам на баланс, listed — сейчас в продаже, views — просмотры активных лотов.

Запрос

bash
curl -s https://hqclouds.com/api/v1/market/sales \
  -H "Authorization: Bearer $HQC_TOKEN"

Ответ

200 OK
{
  "ok": true,
  "stats": {
    "sold": 3,
    "revenue": "747.00",
    "commission": "74.70",
    "proceeds": "672.30",
    "listed": 5,
    "views": 214
  },
  "items": [
    {
      "id": "mko_7c1e3a5b9d0f2a4c6e8b1d3f",
      "domain": "example.com",
      "price": "249.00",
      "commission": "24.90",
      "proceeds": "224.10",
      "currency": "USD",
      "sold_at": "2026-09-28 14:03:11"
    }
  ],
  "total": 3,
  "page": 1,
  "pages": 1,
  "per_page": 50
}

Тематики лотов (category, theme)

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»: отзыв действует мгновенно. Создайте новый ключ и замените токен в своей программе.

Готовы начать?

Создайте ключ в кабинете — это бесплатно и займёт минуту.