Void API — твои домены по REST.
Проверка доступности, регистрация и продление, смена nameservers, подключение домена к Cloudflare и управление его DNS, защитными переключателями и редиректами — из своего кода, на том же аккаунте и балансе, что и бот.
Вебхуки
мы сами стучимся к тебе, когда с доменом что-то происходитЗарегистрируй HTTPS-адрес — и мы будем присылать на него подписанные JSON-события. Главное — попадание домена в блок-лист (Google Safe Browsing, MetaMask, hold у регистратора), но есть и регистрация, продление, истечение. До 5 адресов на аккаунт. События ставятся в очередь и повторяются с нарастающей паузой (1 мин → 5 → 30 → 2 ч → 6 ч → 24 ч); адрес, не принявший 50 доставок подряд, выключается (active: false), пока ты его не включишь снова.
События
| событие | когда | data |
|---|---|---|
domain.blocked | 10-минутная проверка нашла имя в новом блок-листе | domainId, domain, flags[] (новые: google · metamask · registrar), allFlags[] |
domain.unblocked | флаг снят | domainId, domain, cleared[], allFlags[] |
domain.registered | регистрация прошла (бот или API) | domainId, domain, price, expiresAt |
domain.renewed | ручное или автоматическое продление | domainId, domain, price, expiresAt |
domain.expiring | за 7, 3 и 1 день до истечения | domainId, domain, daysLeft, expiresAt, autoRenew |
domain.expired | дата истекла; открылось 30-дневное окно продления | domainId, domain, expiresAt, renewableUntil |
ping | ты вызвал /test | message |
Формат доставки
POST https://your.host/void-webhook
Content-Type: application/json
X-Void-Event: domain.blocked
X-Void-Delivery: 5c1b0f7e-… # уникален для доставки — используй для идемпотентности
X-Void-Timestamp: 1756731600 # unix-секунды
X-Void-Signature: sha256=8f3c… # HMAC-SHA256(secret, timestamp + "." + raw body)
{ "id": "5c1b0f7e-…", "event": "domain.blocked", "createdAt": "2026-09-01T13:00:00.000Z",
"data": { "domainId": "0a79…", "domain": "example.org", "flags": ["google"], "allFlags": ["google"] } }Отвечай 2xx в течение 10 секунд; всё остальное (и редирект тоже) считается ошибкой и повторяется. Проверяй подпись по сырому телу до разбора JSON и отбрасывай метки времени старше нескольких минут:
import { createHmac, timingSafeEqual } from "node:crypto";
export function verify(secret, headers, rawBody) {
const ts = headers["x-void-timestamp"];
if (Math.abs(Date.now() / 1000 - Number(ts)) > 300) return false;
const expected = "sha256=" + createHmac("sha256", secret).update(`${ts}.${rawBody}`).digest("hex");
const got = headers["x-void-signature"] ?? "";
return got.length === expected.length && timingSafeEqual(Buffer.from(got), Buffer.from(expected));
}Список имён событий, на которые можно подписаться.
{ "ok": true, "data": [ { "id": "b2e1…", "url": "https://your.host/void-webhook", "events": ["domain.blocked", "domain.unblocked"],
"active": true, "failures": 0, "lastStatus": 200, "lastDeliveredAt": "2026-09-01T13:00:02.000Z", "createdAt": "…" } ] }| тело | тип | |
|---|---|---|
urlобязательно | URL | публичный https:// адрес (без localhost / приватных сетей / логина-пароля в URL) |
events | string[] | подмножество событий; пусто или не указано = все |
{ "url": "https://your.host/void-webhook", "events": ["domain.blocked", "domain.unblocked"] }
{ "ok": true, "data": { "id": "b2e1…", "url": "…", "events": ["domain.blocked", "domain.unblocked"], "active": true, …,
"secret": "whsec_…" } } // секрет возвращается только здесь — сохрани{ "active": true | false } — поставить адрес на паузу или включить обратно после автоотключения (счётчик ошибок сбрасывается).
Удаляет адрес и историю доставок.
Ставит в очередь событие ping; через ~15 секунд оно появится в /deliveries.
Выдаёт новый секрет (показывается один раз); доставки, поставленные в очередь после вызова, подписаны уже им.
{ "ok": true, "data": [ { "id": "5c1b…", "event": "ping", "status": "SENT", "attempts": 1, "lastStatus": 200, "lastError": null,
"createdAt": "…", "sentAt": "…", "nextAt": null } ] } // status: PENDING · SENT · FAILED