# piv.day API Reference Полный справочник REST API piv.day. Содержит все эндпойнты, тела запросов, форматы ответов, коды ошибок и вебхуки. Скачано с https://piv.day/api/docs для использования с ИИ-ассистентами. --- ## Начало работы REST API на Business-тарифе. Bearer-токены, JSON, идемпотентные эндпойнты, предсказуемые коды ошибок. Документация ниже описывает каждый эндпойнт с примером запроса и ответа. ### Base URL ``` https://app.piv.day/api/v1 ``` Все эндпойнты живут под этим префиксом. Окружение одно — отдельных staging-доменов нет. ### Аутентификация ``` Authorization: Bearer YOUR_API_KEY ``` Ключи создаются в дашборде в разделе `Настройки → API Keys`. У каждого ключа — гранулярные разрешения (чтение номеров, отправка SMS, покупка прокси и т.д.). Скомпрометированный токен ротируется в один клик без перерегистрации команды. ### Аккаунт **200 OK** ``` curl https://app.piv.day/api/v1/account \ -H "Authorization: Bearer YOUR_API_KEY" ``` **Один служебный эндпойнт — баланс и email текущего аккаунта. Удобно проверить, что ключ рабочий и аутентификация настроена правильно.** ``` { "success": true, "data": { "user_id": "usr-uuid-...", "balance": 150.50, "email": "u***@example.com", "team_id": null, "is_team_member": false } } ``` GET /api/v1/account ### Формат ответа ``` { "success": true, "data": { ... } } ``` Все ответы — JSON. При ошибке `success` = `false`, а тело содержит `error.code` и `error.message`. ### Rate limits **100 запросов в минуту на каждый API-ключ. Лимит общий для всех эндпойнтов. Если упёрлись в потолок — пишите в Telegram-поддержку, поднимем под нагрузку без долгих согласований. При превышении приходит `429 RATE_LIMITED` и заголовок `Retry-After` — сколько секунд подождать до следующего запроса.** ``` HTTP/1.1 429 Too Many Requests Retry-After: 12 { "success": false, "error": { "code": "RATE_LIMITED", "message": "Rate limit exceeded, retry in 12s" } } ``` 429 Too Many Requests ## Номера Покупка, продление, восстановление номеров. Приём и отправка SMS. Запуск Google QR-верификации. Подписка на события через вебхуки. ### Список стран и цен `GET /api/v1/numbers/countries` Возвращает страны, доступные для покупки, с актуальной ценой и направлениями SMS. Все цены — итоговые, с учётом скидки вашей подписки. **Поля ответа** | Поле | Тип | Описание | | --- | --- | --- | | `country_code` | string | Двухбуквенный ISO-код страны (например `SE`). | | `price_per_month` | number | Итоговая цена для вашего тарифа — то, что реально спишется при покупке. Если у вас Premium или Business, скидка уже включена. | | `base_price` | number | Цена без скидок (Free-тариф). Возвращается для сравнения — увидеть, сколько экономит подписка. | | `can_send_sms` | boolean | Можно ли с этого номера отправлять исходящие SMS. | | `can_receive_sms` | boolean | Можно ли принимать входящие SMS. | | `sms_send_price` | number\|null | Цена за исходящее SMS — тоже с учётом тарифа. `null`, если отправка из этой страны недоступна. | **curl** ```bash curl https://app.piv.day/api/v1/numbers/countries \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": [ { "country_code": "SE", "price_per_month": 4.00, "base_price": 5.00, "can_send_sms": true, "can_receive_sms": true, "sms_send_price": 0.25 }, { "country_code": "GB", "price_per_month": 3.00, "base_price": 3.00, "can_send_sms": true, "can_receive_sms": true, "sms_send_price": 0.20 } ] } ``` ### Список номеров аккаунта `GET /api/v1/numbers` Возвращает страницу номеров аккаунта с фильтрами по стране, статусу и поиском по номеру или кастомному имени. **Query-параметры** | Поле | Тип | Описание | | --- | --- | --- | | `limit` | integer | Количество записей на странице (по умолчанию 50, максимум 200). | | `offset` | integer | Смещение для пагинации. | | `country` | string | ISO-код страны для фильтра. | | `status` | string | Один из `active`, `expired`, `pending_restore`. | | `search` | string | Подстрока для поиска по номеру или кастомному имени. | **curl** ```bash curl "https://app.piv.day/api/v1/numbers?country=SE&status=active&limit=10" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "numbers": [ { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "country_code": "SE", "status": "active", "created_at": "2026-05-01T10:00:00Z", "expires_at": "2026-05-31T10:00:00Z", "auto_renew": false, "custom_name": "Office line", "purchased_at": "2026-05-01T10:00:00Z", "next_renewal_date": "2026-05-31T10:00:00Z", "tags": ["support"], "can_send_sms": true, "can_receive_sms": true } ], "pagination": { "total": 1, "limit": 10, "offset": 0 } } } ``` ### Один номер по ID `GET /api/v1/numbers/{piv_num_id}` Полная карточка номера: статус, даты, авто-продление, теги, разрешённые SMS-направления. **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Номер не найден или не принадлежит аккаунту. | **curl** ```bash curl https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "country_code": "SE", "status": "active", "created_at": "2026-05-01T10:00:00Z", "expires_at": "2026-05-31T10:00:00Z", "auto_renew": false, "custom_name": "Office line", "purchased_at": "2026-05-01T10:00:00Z", "next_renewal_date": "2026-05-31T10:00:00Z", "tags": ["support"], "can_send_sms": true, "can_receive_sms": true } } ``` ### Покупка номера `POST /api/v1/numbers/purchase` Покупает один номер выбранной страны на указанный срок. Сумма списывается с баланса аккаунта. Возвращает `piv_num_id`, который дальше используется во всех операциях с номером. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `country_code` * | string | ISO-код страны. | | `duration_months` * | integer | Срок аренды в месяцах (минимум 1). | | `auto_renew` * | boolean | Включить ли авто-продление сразу после покупки. | | `custom_name` | string | Опциональное человекочитаемое имя для номера. | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `COUNTRY_NOT_AVAILABLE` | 400 | Страна недоступна или для неё нет цен. | | `NO_NUMBERS_AVAILABLE` | 400 | В указанной стране сейчас нет свободных номеров. | | `INSUFFICIENT_BALANCE` | 402 | На балансе не хватает средств для покупки. | | `VALIDATION_ERROR` | 400 | Невалидные поля в теле запроса. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/purchase \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "country_code": "SE", "duration_months": 1, "auto_renew": false, "custom_name": "My Sweden Number" }' ``` **200 OK** ```json { "success": true, "cost": 5.00, "numbers": [ { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "country_code": "SE", "phone_number": "+46764794425", "created_at": "2026-05-01T10:00:00Z", "expires_at": "2026-05-31T10:00:00Z", "auto_renew": false, "custom_name": "My Sweden Number" } ] } ``` ### Продлить номер `POST /api/v1/numbers/{piv_num_id}/renew` Продление активного номера на указанный срок. Стоимость списывается с баланса в момент вызова. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `duration_months` * | integer | На сколько месяцев продлить. | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Номер не найден или не принадлежит аккаунту. | | `COUNTRY_NOT_AVAILABLE` | 400 | Для страны номера не найдены цены. | | `INSUFFICIENT_BALANCE` | 402 | Не хватает средств для продления. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/renew \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "duration_months": 1 }' ``` **200 OK** ```json { "success": true, "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "old_expires_at": "2026-05-31T10:00:00Z", "new_expires_at": "2026-06-30T10:00:00Z", "cost": 5.00 } } ``` ### Обновить номер `PATCH /api/v1/numbers/{piv_num_id}` Сейчас редактируется только кастомное имя номера. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `custom_name` * | string | Новое имя номера. | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Номер не найден или не принадлежит аккаунту. | | `VALIDATION_ERROR` | 400 | Невалидное значение в теле запроса. | **curl** ```bash curl -X PATCH https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "custom_name": "Support line" }' ``` **200 OK** ```json { "success": true, "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "country_code": "SE", "status": "active", "custom_name": "Support line", "auto_renew": false, "expires_at": "2026-05-31T10:00:00Z", "tags": [] } } ``` ### Управление авто-продлением `PATCH /api/v1/numbers/{piv_num_id}/auto-renewal` Включает или выключает авто-продление номера. Когда включено — продление списывается с баланса автоматически за 24 часа до истечения. Если средств не хватит, номер истечёт; вернуть его можно через `POST /numbers/restore` в течение 7 дней. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `auto_renew` * | boolean | Новое значение флага авто-продления. | **curl** ```bash curl -X PATCH https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/auto-renewal \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "auto_renew": true }' ``` **200 OK** ```json { "success": true, "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "auto_renew": true } } ``` ### Восстановить просроченные номера `POST /api/v1/numbers/restore` Возвращает просроченные номера в течение 7-дневного окна. Передайте массив `piv_num_id` — номера вернутся с сохранением SMS-истории и настроек. Стоимость восстановления выше, чем покупки нового номера (включён множитель восстановления) — точные цифры видны в дашборде перед подтверждением. Финальный статус по каждому номеру придёт на вебхук `number.restore_completed`; за неуспешные деньги автоматически возвращаются на баланс. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `piv_num_ids` * | string[] | Массив ID номеров для восстановления. | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `NO_RESTORABLE_NUMBERS` | 404 | Ни один из переданных номеров нельзя восстановить (истёк 7-дневный срок или номер не ваш). | | `INSUFFICIENT_BALANCE` | 402 | Не хватает средств на оплату восстановления. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/restore \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "piv_num_ids": [ "vzPA1-kHKSg-EAL7e-Jqd3o", "abc12-defgh-ijklm-nopqr" ] }' ``` **200 OK** ```json { "success": true, "queued": 2, "skipped": 0, "total_charged": 9.00, "numbers": [ { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "status": "pending" } ] } ``` ### История SMS по номеру `GET /api/v1/numbers/{piv_num_id}/sms` Возвращает входящие и исходящие сообщения по номеру в обратном хронологическом порядке. **Query-параметры** | Поле | Тип | Описание | | --- | --- | --- | | `limit` | integer | Сколько сообщений вернуть (по умолчанию 50, максимум 200). | | `offset` | integer | Смещение для пагинации. | **curl** ```bash curl "https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/sms?limit=20" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "messages": [ { "id": "42", "from_number": "+46764794425", "to_number": "+14155551234", "message_body": "Hello from piv.day", "direction": "outbound", "status": "delivered", "received_at": "2026-05-22T11:30:00Z" }, { "id": "41", "from_number": "+14155551234", "to_number": "+46764794425", "message_body": "Hey, got your message!", "direction": "inbound", "status": "received", "received_at": "2026-05-22T11:35:00Z" } ], "pagination": { "total": 2, "limit": 20, "offset": 0 } } } ``` ### Отправить SMS `POST /api/v1/numbers/{piv_num_id}/sms/send` Доступно для стран, где разрешена исходящая отправка (например CA, GB, SE). Стоимость сообщения списывается с баланса в момент отправки. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `to_number` * | string | Номер получателя в международном формате (E.164). | | `message_body` * | string | Текст сообщения. Поддерживаются GSM-7 и UCS-2. | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Номер не найден или не принадлежит аккаунту. | | `NUMBER_EXPIRED` | 403 | Номер уже истёк. | | `NUMBER_NOT_ACTIVE` | 400 | Номер сейчас в состоянии, не разрешающем отправку. | | `INSUFFICIENT_BALANCE` | 402 | Не хватает средств для отправки. | | `INVALID_MESSAGE_FORMAT` | 400 | Тело сообщения превышает допустимую длину или содержит запрещённые символы. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/sms/send \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to_number": "+14155551234", "message_body": "Hello from piv.day" }' ``` **200 OK** ```json { "success": true, "data": { "message_id": "42", "from_number": "+46764794425", "to_number": "+14155551234", "message_body": "Hello from piv.day", "status": "queued", "created_at": "2026-05-22T11:30:00Z" } } ``` ### Запуск Google QR-верификации `POST /api/v1/numbers/{piv_num_id}/verify` Запускает Google QR-верификацию по присланному URL. Результат — успех или ошибка — придёт на вебхук verify.completed или verify.failed. Стоимость списывается с баланса в момент запуска. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `gv_url` * | string | Полный URL Google-верификации (берётся со страницы Google). | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Номер не найден или не ваш. | | `NUMBER_NOT_ACTIVE` | 400 | Номер не в активном статусе. | | `SMS_DISABLED` | 400 | Отправка SMS отключена для этого номера. | | `INSUFFICIENT_BALANCE` | 402 | Не хватает средств для верификации. | | `PROXY_DEAD` | 502 | Прокси недоступен — баланс возвращён. | | `QUEUE_FULL` | 503 | Сервер занят, попробуйте позже — баланс возвращён. | | `SERVER_UNAVAILABLE` | 503 | Сервер автоматизации недоступен — баланс возвращён. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/verify \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "gv_url": "https://gv.google.com/..." }' ``` **202 Accepted** ```json { "success": true, "message": "Verification initiated" } ``` ## Прокси Резидентский IPv6 в десятках стран. Покупка партиями, продление, Restore с теми же логином и паролем, экспорт в нужном формате. ### Список серверов `GET /api/v1/proxy/servers` Список доступных прокси-серверов с ценами. **curl** ```bash curl https://app.piv.day/api/v1/proxy/servers \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "servers": [ { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "EU-DE-01", "country": "DE", "socks5_port": 1080, "http_port": 3128, "price_per_proxy": 0.50 }, { "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "name": "EU-NL-01", "country": "NL", "socks5_port": 1080, "http_port": 3128, "price_per_proxy": 0.45 } ] } } ``` ### Список заказов `GET /api/v1/proxy/orders` Список ваших заказов прокси с возможностью фильтрации по статусу или поисковому запросу. **Query-параметры** | Поле | Тип | Описание | | --- | --- | --- | | `limit` | integer | Количество записей. По умолчанию: 100, максимум: 500. | | `offset` | integer | Смещение для пагинации. | | `status` | string | Фильтр по статусу: `active`, `expired`. | | `search` | string | Поиск по заказу. | **curl** ```bash curl "https://app.piv.day/api/v1/proxy/orders?status=active&limit=20" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "orders": [ { "id": "ord-uuid-...", "country": "DE", "quantity": 10, "price_per_proxy": 0.50, "price_total": 5.00, "status": "active", "purchased_at": "2026-01-01T00:00:00Z", "expires_at": "2026-02-01T00:00:00Z" } ], "pagination": { "total": 1, "limit": 20, "offset": 0 } } } ``` ### Один заказ `GET /api/v1/proxy/orders/{id}` Получить детали конкретного заказа, включая список прокси-учётных данных. **curl** ```bash curl https://app.piv.day/api/v1/proxy/orders/ord-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "order": { "id": "ord-uuid-...", "country": "DE", "quantity": 10, "price_per_proxy": 0.50, "price_total": 5.00, "status": "active", "purchased_at": "2026-01-01T00:00:00Z", "expires_at": "2026-02-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "items": [ { "login": "user1", "password": "pass1", "host": "185.1.2.3", "socks5_port": 1080, "http_port": 3128, "ipv6": "2a00:1:2:3::1" } ] } } } ``` ### Купить прокси `POST /api/v1/proxy/purchase` Купить прокси на выбранном сервере. Один запрос создаёт один заказ с N прокси (до 500). Bulk-заказов нет — при необходимости вызывайте метод повторно. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `server_id` * | string | ID сервера из `GET /proxy/servers`. | | `quantity` * | integer | Сколько прокси купить (1–500). | | `months` * | integer | Срок аренды в месяцах (1–12). | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `INSUFFICIENT_BALANCE` | 402 | Не хватает средств. | | `NOT_FOUND` | 404 | Прокси-сервер не найден или неактивен. | | `VALIDATION_ERROR` | 400 | Некорректное тело запроса. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/proxy/purchase \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "server_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "quantity": 5, "months": 1 }' ``` **200 OK** ```json { "success": true, "data": { "order": { "id": "ord-uuid-...", "country": "DE", "quantity": 5, "price_total": 2.50, "status": "active", "expires_at": "2026-02-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "items": [ { "login": "user1", "password": "pass1", "host": "185.1.2.3", "socks5_port": 1080, "http_port": 3128, "ipv6": "2a00:1:2:3::1" }, { "login": "user2", "password": "pass2", "host": "185.1.2.3", "socks5_port": 1080, "http_port": 3128, "ipv6": "2a00:1:2:3::2" } ] } } } ``` ### Продлить заказ `POST /api/v1/proxy/orders/{id}/renew` Продлить активный заказ прокси на дополнительное количество месяцев. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `months` * | integer | Сколько месяцев добавить. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../renew \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "months": 1 }' ``` **200 OK** ```json { "success": true, "data": { "order_id": "ord-uuid-...", "cost": 5.00, "new_expires_at": "2026-03-01T00:00:00Z" } } ``` ### Restore просроченного заказа `POST /api/v1/proxy/orders/{id}/restore` Восстановить истёкший заказ прокси без перепокупки. Логин, пароль, IPv6-адреса, страна и привязки — те же. Срок продлевается на 1 месяц. Антидетект перенастраивать не надо. **curl** ```bash curl -X POST https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../restore \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "order_id": "ord-uuid-...", "quantity": 10, "total_cost": 5.00, "expires_at": "2026-03-01T00:00:00Z" } } ``` ### Экспорт списка прокси `GET /api/v1/proxy/orders/{id}/export` Экспортировать учётные данные прокси заказа в виде текстового списка (login:password@host:port). **Query-параметры** | Поле | Тип | Описание | | --- | --- | --- | | `format` | string | Формат экспорта: `socks5`, `http` или `both` (по умолчанию `socks5`). | **curl** ```bash curl "https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../export?format=socks5" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "content": "user1:pass1@1.2.3.4:1080\nuser2:pass2@1.2.3.4:1080", "filename": "piv-day-proxy-ord-uuid--socks5.txt", "format": "socks5", "count": 2 } } ``` ## Домены Поиск и регистрация без KYC, автоматический Cloudflare и SSL, управление DNS-записями и NS-серверами через API. ### Проверка доступности `GET /api/v1/domains/search` Проверить доступность и стоимость регистрации домена. **Query-параметры** | Поле | Тип | Описание | | --- | --- | --- | | `q` * | string | Имя домена для поиска, например `mysite.com`. | **curl** ```bash curl "https://app.piv.day/api/v1/domains/search?q=mysite.com" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "domain": "mysite.com", "available": true, "create_price": 12.50, "renew_price": 12.50, "currency": "USD" } } ``` ### Список доменов `GET /api/v1/domains` Список ваших зарегистрированных доменов с возможностью фильтрации. **Query-параметры** | Поле | Тип | Описание | | --- | --- | --- | | `limit` | integer | Количество записей. По умолчанию: 100, максимум: 500. | | `offset` | integer | Смещение для пагинации. | | `status` | string | Статус домена: `active`, `pending`, `expired`. | | `cloudflare` | string | Фильтр по статусу Cloudflare: `true` или `false`. | | `auto_renew` | string | Фильтр по автопродлению: `true` или `false`. | | `search` | string | Поиск по доменному имени. | **curl** ```bash curl "https://app.piv.day/api/v1/domains?status=active&limit=20" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "domains": [ { "id": "dom-uuid-...", "domain_name": "mysite.com", "status": "active", "registered_at": "2026-01-01T00:00:00Z", "expires_at": "2027-01-01T00:00:00Z", "auto_renew": true, "cloudflare_enabled": true, "cloudflare_status": "active", "ssl_type": "lets_encrypt", "ssl_status": "active", "ssl_mode": "full", "ssl_expires_at": "2026-04-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z" } ], "pagination": { "total": 1, "limit": 20, "offset": 0 } } } ``` ### Регистрация домена `POST /api/v1/domains` Зарегистрировать новый домен. Запрос асинхронный — возвращает `queue_id` для отслеживания. Cloudflare ВКЛ: поле `nameservers` передавать нельзя, можно опционально передать `dns_records` и `ssl_mode`. Cloudflare ВЫКЛ: поля `dns_records` и `ssl_mode` передавать нельзя, `nameservers` обязательно (не менее 2). NS-серверы Cloudflare мы никогда не раскрываем. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `domain` * | string | Имя домена для регистрации, например `mysite.com`. | | `period` * | integer | Срок регистрации в годах (1–10). | | `cloudflare` * | boolean | Подключить домен к Cloudflare автоматически. | | `auto_renew` * | boolean | Включить автоматическое продление. | | `ssl_mode` | string | `flexible` \| `full` \| `strict`. Только при `cloudflare: true`. | | `nameservers` | string[] | Обязательно при `cloudflare: false` (≥2 NS). Запрещено при `cloudflare: true`. | | `dns_records` | object[] | Начальные DNS-записи. Только при `cloudflare: true`. | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `DOMAIN_NOT_AVAILABLE` | 400 | Домен недоступен для регистрации. | | `INSUFFICIENT_BALANCE` | 402 | Не хватает средств. | | `VALIDATION_ERROR` | 400 | Некорректное тело запроса. | **Cloudflare ВКЛ** ```bash curl -X POST https://app.piv.day/api/v1/domains \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domain": "mysite.com", "period": 1, "cloudflare": true, "auto_renew": true, "ssl_mode": "full", "dns_records": [ { "type": "A", "name": "@", "content": "1.2.3.4", "proxied": true } ] }' ``` **Cloudflare ВЫКЛ — свои NS** ```bash curl -X POST https://app.piv.day/api/v1/domains \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domain": "mysite.com", "period": 1, "cloudflare": false, "auto_renew": false, "nameservers": ["ns1.myhost.com", "ns2.myhost.com"] }' ``` **202 Accepted** ```json { "success": true, "data": { "queue_id": "que-uuid-...", "domain": { "id": "dom-uuid-...", "domain_name": "mysite.com", "status": "purchasing", "period": 1, "cloudflare_enabled": true, "auto_renew": true, "ssl_mode": "full", "created_at": "2026-01-01T00:00:00Z" } } } ``` ### Статус задачи регистрации `GET /api/v1/domains/queue/{id}` Проверить статус записи очереди регистрации или продления домена. При статусе `completed` в ответе сразу полная карточка домена — отдельный запрос к `/domains/{id}` не нужен. **curl** ```bash curl https://app.piv.day/api/v1/domains/queue/que-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` **pending / processing** ```json { "success": true, "data": { "queue_id": "que-uuid-...", "domain": "mysite.com", "status": "pending" } } ``` **completed — полная карточка** ```json { "success": true, "data": { "queue_id": "que-uuid-...", "status": "completed", "domain": { "id": "dom-uuid-...", "domain_name": "mysite.com", "status": "active", "registered_at": "2026-01-01T12:00:00Z", "expires_at": "2027-01-01T12:00:00Z", "auto_renew": true, "cloudflare_enabled": true, "cloudflare_status": "active", "ssl_type": "lets_encrypt", "ssl_status": "active", "ssl_mode": "full", "ssl_expires_at": "2026-04-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T12:00:00Z", "dns_records": [ { "name": "@", "type": "A", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true } ] } } } ``` ### Один домен `GET /api/v1/domains/{id}` Получить полную информацию о зарегистрированном домене. Поле `nameservers` присутствует только если `cloudflare_enabled: false`. **curl** ```bash curl https://app.piv.day/api/v1/domains/dom-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "domain": { "id": "dom-uuid-...", "domain_name": "mysite.com", "status": "active", "registered_at": "2026-01-01T12:00:00Z", "expires_at": "2027-01-01T12:00:00Z", "auto_renew": true, "cloudflare_enabled": true, "cloudflare_status": "active", "ssl_type": "lets_encrypt", "ssl_status": "active", "ssl_mode": "full", "ssl_expires_at": "2026-04-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T12:00:00Z", "dns_records": [ { "name": "@", "type": "A", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true }, { "name": "www", "type": "CNAME", "content": "mysite.com", "ttl": 1, "priority": null, "proxied": true } ] } } } ``` ### Продлить домен `POST /api/v1/domains/{id}/renew` Продлить регистрацию домена. Возвращает `queue_id` для отслеживания. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `period` * | integer | На сколько лет продлить. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../renew \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "period": 1 }' ``` **202 Accepted** ```json { "success": true, "data": { "queue_id": "que-uuid-...", "domain_id": "dom-uuid-...", "expires_at": "2027-01-01T12:00:00Z" } } ``` ### Авто-продление `POST /api/v1/domains/{id}/auto-renew` Включить или отключить автоматическое продление домена. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `auto_renew` * | boolean | Новое значение флага. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../auto-renew \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "auto_renew": true }' ``` **200 OK** ```json { "success": true, "data": { "id": "dom-uuid-...", "auto_renew": true } } ``` ### DNS-записи домена `GET /api/v1/domains/{id}/dns` Список DNS-записей домена (через Cloudflare). **curl** ```bash curl https://app.piv.day/api/v1/domains/dom-uuid-.../dns \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "records": [ { "id": "rec-uuid-...", "type": "A", "name": "@", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true } ] } } ``` ### Добавить DNS-запись `POST /api/v1/domains/{id}/dns` Создать новую DNS-запись. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `type` * | string | Тип записи: `A`, `AAAA`, `CNAME`, `MX`, `TXT` и др. | | `name` * | string | Имя записи, например `@` или `subdomain`. | | `content` * | string | Значение записи. | | `ttl` | integer | TTL в секундах (`1` = авто). | | `proxied` | boolean | Проксировать через Cloudflare. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../dns \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "A", "name": "@", "content": "1.2.3.4", "ttl": 1, "proxied": true }' ``` **201 Created** ```json { "success": true, "data": { "record": { "id": "rec-uuid-...", "type": "A", "name": "@", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true } } } ``` ### Изменить DNS-запись `PUT /api/v1/domains/{id}/dns/{recordId}` Обновить существующую DNS-запись по ID. Перезаписываются только переданные поля. **curl** ```bash curl -X PUT https://app.piv.day/api/v1/domains/dom-uuid-.../dns/rec-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": "5.6.7.8" }' ``` ### Удалить DNS-запись `DELETE /api/v1/domains/{id}/dns/{recordId}` Удалить DNS-запись по ID. **curl** ```bash curl -X DELETE https://app.piv.day/api/v1/domains/dom-uuid-.../dns/rec-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` ### Включить Cloudflare `POST /api/v1/domains/{id}/cloudflare` Включить Cloudflare для домена. NS-серверы Cloudflare не отдаём — делегирование настраиваем на своей стороне сами. Отключение Cloudflare через этот эндпоинт не поддерживается. **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../cloudflare \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": true }' ``` **200 OK** ```json { "success": true, "data": { "domain_id": "dom-uuid-...", "ssl_mode": "flexible" } } ``` ### Сменить NS-серверы `POST /api/v1/domains/{id}/ns-servers` Задать произвольные NS-серверы для домена. **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../ns-servers \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "nameservers": ["ns1.example.com", "ns2.example.com"] }' ``` **200 OK** ```json { "success": true, "data": { "nameservers": [ { "nameserver": "ns1.example.com", "order_index": 1 }, { "nameserver": "ns2.example.com", "order_index": 2 } ] } } ``` ## Вайты Генерация белых страниц по нише и тиру. Каждый сайт уникален. Смена домена и контактов — без перегенерации. ### Список тиров `GET /api/v1/whites/tiers` Список доступных тарифов генерации с ценами. `price` — цена за генерацию уже под ваш аккаунт (с учётом подписки), одна цифра. Качество `quality: "premium"` стоит дороже (считается при создании). Блог только у `v2_tier3`: первые 3 статьи включены, за каждую дополнительную (до 20) — `extra_article_price`. **curl** ```bash curl https://app.piv.day/api/v1/whites/tiers \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "tiers": [ { "tier_key": "v2_tier1", "name": "Landing", "generator_version": "v2", "min_articles": 0, "max_articles": 0, "price": 3.00, "extra_article_price": null }, { "tier_key": "v2_tier2", "name": "Multi-page", "generator_version": "v2", "min_articles": 0, "max_articles": 0, "price": 6.00, "extra_article_price": null }, { "tier_key": "v2_tier3", "name": "Full + Blog", "generator_version": "v2", "min_articles": 3, "max_articles": 20, "price": 10.00, "extra_article_price": 1.50 } ] } } ``` ### Список вайтов `GET /api/v1/whites` Список ваших задач генерации с возможностью фильтрации. **Query-параметры** | Поле | Тип | Описание | | --- | --- | --- | | `limit` | integer | Количество записей. По умолчанию: 100, максимум: 500. | | `offset` | integer | Смещение для пагинации. | | `status` | string | `queued` \| `processing` \| `done` \| `failed`. | | `tier_key` | string | `v2_tier1` \| `v2_tier2` \| `v2_tier3`. | **curl** ```bash curl "https://app.piv.day/api/v1/whites?status=done&limit=20" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "whites": [ { "id": "job-uuid-...", "name": "My White", "status": 10, "tier_key": "v2_tier3", "quality": "standard", "niche": "IT Consulting", "country": "DE", "language": "de", "domain": "mysite.com", "result_url": null, "created_at": "2026-01-01T00:00:00Z" } ], "pagination": { "total": 1, "limit": 20, "offset": 0 } } } ``` ### Запустить генерацию `POST /api/v1/whites` Поставить задачу генерации вайт-страницы в очередь. Оплата снимается сразу. Финальный статус приходит на вебхук `white.completed` / `white.failed` или проверяется через `GET /whites/{id}`. **Тело запроса** | Поле | Тип | Описание | | --- | --- | --- | | `name` * | string | Название задания (2–20 символов). | | `tier_key` * | string | `v2_tier1` \| `v2_tier2` \| `v2_tier3`. | | `niche` * | string | Тематика сайта (до 25 символов). | | `country` * | string | Код страны (ISO 3166-1 alpha-2). | | `language` * | string | Основной язык сайта (ISO 639-1). | | `quality` | string | `standard` \| `premium` (по умолчанию `standard`). | | `languages` | string[] | Список языков. Первый включён в цену, каждый следующий — доплата. | | `domain` | string | Полный домен (напр. `example.com`). Без автоподстановки. | | `email` | string | Полный email (напр. `info@example.com`). Без автоподстановки. | | `phone` | string | Телефон контакта. | | `address` | string | Адрес компании. | | `legal_name` | string | Юридическое название. | | `style_hint` | string | Стиль дизайна (Random, Минималистичный, Корпоративный и др.). | | `keywords` | string[] | Ключевые слова для SEO. | | `banned_words` | string[] | Слова, запрещённые в контенте. | | `blog_count` | integer | Кол-во статей блога 3–20. Только для `v2_tier3`. За статьи сверх 3 — доплата. | | `contacts_mode` | string | `same` \| `template`. | | `contacts_template` | string | Шаблон контактной страницы (при `contacts_mode=template`). | | `facebook` | string | Полный URL страницы Facebook. | | `instagram` | string | Полный URL профиля Instagram. | | `linkedin` | string | Полный URL профиля LinkedIn. | | `youtube` | string | Полный URL канала YouTube. | | `tiktok` | string | Полный URL профиля TikTok. | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `INSUFFICIENT_BALANCE` | 402 | Не хватает средств. | | `INVALID_TIER` | 400 | Тариф с таким ключом не найден. | | `VALIDATION_ERROR` | 400 | Некорректное тело запроса. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/whites \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Tech Blog DE", "tier_key": "v2_tier3", "niche": "IT Consulting", "country": "DE", "language": "de", "quality": "premium", "languages": ["de", "en"], "domain": "techblog-de.com", "email": "info@techblog-de.com", "phone": "+49 30 123456", "address": "Berliner Str. 1, 10115 Berlin", "legal_name": "TechBlog GmbH", "style_hint": "Корпоративный", "keywords": ["IT", "consulting", "cloud"], "banned_words": ["cheap", "free"], "blog_count": 8, "contacts_mode": "same", "facebook": "https://facebook.com/techblogde", "instagram": "https://instagram.com/techblogde", "linkedin": "https://linkedin.com/company/techblogde" }' ``` **200 OK** ```json { "success": true, "data": { "status": "queued", "white": { "id": "job-uuid-...", "name": "Tech Blog DE", "status": 0, "tier_key": "v2_tier3", "quality": "premium", "niche": "IT Consulting", "country": "DE", "language": "de", "domain": "techblog-de.com", "result_url": null, "created_at": "2026-01-01T00:00:00Z" } } } ``` ### Один вайт `GET /api/v1/whites/{id}` Получить текущее состояние задачи генерации. **curl** ```bash curl https://app.piv.day/api/v1/whites/job-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "white": { "id": "job-uuid-...", "name": "Tech Blog DE", "status": 10, "tier_key": "v2_tier3", "quality": "premium", "niche": "IT Consulting", "country": "DE", "language": "de", "domain": "techblog-de.com", "result_url": null, "created_at": "2026-01-01T00:00:00Z" } } } ``` ### Скачать архив `GET /api/v1/whites/{id}/download` Получить подписанную короткоживущую ссылку на готовый архив вайт-страницы. Ссылка действует ~5 минут (см. `expires_at`). Если истекла — просто запроси `/download` ещё раз, выдадим новую. Если вайт ещё не сгенерирован, вернётся `409 NOT_READY`. **Query-параметры** | Поле | Тип | Описание | | --- | --- | --- | | `format` | string | Формат архива. По умолчанию `php`. | **Ошибки** | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `NOT_READY` | 409 | Вайт ещё генерируется — повтори запрос после `white.completed`. | **curl** ```bash curl "https://app.piv.day/api/v1/whites/job-uuid-.../download?format=php" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "url": "https://strg.piv.day/download//?format=php&token=&filename=.zip", "filename": "example.com_2026-05-28_DE_en.zip", "format": "php", "expires_at": "2026-05-28T14:46:00Z" } } ``` ### Сменить домен и контакты `POST /api/v1/whites/{id}/config` Обновить контактные данные компании в вайт-странице без повторной генерации. **curl** ```bash curl -X POST https://app.piv.day/api/v1/whites/job-uuid-.../config \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "company": "My Brand", "domain": "newdomain.com", "email": "info@newdomain.com", "phone": "+49 30 123456", "address": "Berliner Str. 1, Berlin", "legal": "My Brand GmbH" }' ``` ## Вебхуки На ваш URL отправляется обычный POST с JSON-телом. Формат одинаковый для всех событий: `event_type`, `timestamp` и блок `data`. Ваш сервер должен ответить любым 2xx за 5 секунд. ``` POST Content-Type: application/json User-Agent: piv.day-webhook/1.0 { "event_type": "", "timestamp": "2026-05-22T12:34:56Z", "data": { ... } } ``` **Повторы.** При не-2xx или таймауте — до 3 повторов с задержкой 1 с, 2 с, 4 с. История всех попыток доступна на странице API-ключей в дашборде. Если все три не прошли — событие отмечается как failed, можно переотправить вручную. **Безопасность.** Используйте HTTPS-эндпойнт. Каждый запрос приходит с заголовком `User-Agent: piv.day-webhook/1.0`. URL для вебхуков настраивается в профиле API-ключа. ### Все события | Событие | Когда срабатывает | | --- | --- | | `sms.received` | На ваш номер пришло SMS от доверенного отправителя. | | `sms.status_updated` | Исходящее SMS поменяло статус — например, ушло в доставку или провалилось. | | `number.restore_completed` | Пакетный Restore доехал до конца — приходит финальный итог. | | `verify.completed` | Верификация Google-аккаунта закрылась успешно. | | `verify.failed` | Что-то пошло не так — Google не пропустил. | | `proxy.expires_soon` | До конца аренды заказа прокси осталось около трёх дней. | | `domain.registered` | Заказ на регистрацию закрылся успешно — домен живой. | | `domain.failed` | Заказ не дошёл до конца — частая причина: домен только что заняли. | | `domain.expires_soon` | До истечения домена осталось около недели. | | `white.completed` | Задача генерации вайта закрылась успешно. | | `white.failed` | Задача упала — деньги возвращаются на баланс. | ### Входящее SMS на ваш номер **`sms.received`** Самое частое — коды подтверждения от рекламных сетей. В payload приходит и сырой текст, и автоматически распознанный код (если есть) — можно сразу пробросить в свой воркфлоу без парсинга. SMS от заведомо спамных отправителей через вебхук не присылаются. ```json { "event_type": "sms.received", "timestamp": "2026-05-22T12:34:56Z", "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "text": "Your verification code is 123456", "code": "123456", "country": "SE", "received_at": "2026-05-22T12:34:56Z" } } ``` ### Статус отправленного SMS изменился **`sms.status_updated`** Подходит, если вы шлёте подтверждения от своего имени и хотите знать, что сообщение реально дошло. Если статус failed — в payload приходят код и текст ошибки от оператора. ```json { "event_type": "sms.status_updated", "timestamp": "2026-05-22T12:34:56Z", "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "message_id": "42", "old_status": "sent", "new_status": "delivered", "error_code": null, "error_message": null } } ``` ### Восстановление номеров завершено **`number.restore_completed`** Содержит два списка: какие номера вернулись и какие нет. За не вернувшиеся номера сумма возвращается на баланс — она тоже в payload. Удобно для скриптов: понятно, что просить заново. ```json { "event_type": "number.restore_completed", "timestamp": "2026-05-22T12:34:56Z", "data": { "restored": [ { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "country": "SE" } ], "failed": [ { "piv_num_id": "abc12-defgh-ijklm-nopqr", "phone_number": "+46123456789", "country": "SE", "refunded": 7.50 } ], "total_restored": 1, "total_failed": 1, "total_refunded": 7.50 } } ``` ### Google QR-верификация прошла **`verify.completed`** Если в процессе пришло SMS с кодом — оно уже здесь, не нужно отдельно его забирать. Поля captured_phone и captured_message содержат то, что отправил Google. ```json { "event_type": "verify.completed", "timestamp": "2026-05-22T12:34:56Z", "data": { "task_id": 12, "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "status": "sms_sent", "captured_phone": "+14155551234", "captured_message": "Your Google verification code is 123456", "sms_message_id": 42, "sms_status": "queued" } } ``` ### Google QR-верификация не прошла **`verify.failed`** Поле error_code говорит, что именно: таймаут, отказ, невалидный URL. Сумма за неуспешную верификацию возвращается на баланс автоматически. ```json { "event_type": "verify.failed", "timestamp": "2026-05-22T12:34:56Z", "data": { "task_id": 12, "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "status": "failed", "error_code": "VERIFY_TIMEOUT", "error_message": "Verification timed out" } } ``` ### Прокси скоро истекут **`proxy.expires_soon`** Нужно для тех, кто продлевает не автоматически: успеваете заранее увидеть и решить — продлить или закрыть кампанию. Если хочется, можно подписаться и сразу дёргать POST /proxy/orders/{id}/renew. ```json { "event_type": "proxy.expires_soon", "timestamp": "2026-05-22T12:34:56Z", "data": { "order_id": "ord-uuid-...", "country": "DE", "quantity": 10, "expires_at": "2026-05-25T00:00:00Z" } } ``` ### Домен зарегистрирован **`domain.registered`** Если при покупке вы запросили Cloudflare и SSL, всё уже поднято — флаг cloudflare_enabled покажет статус. Можно сразу добавлять DNS-записи или раскатывать сайт. ```json { "event_type": "domain.registered", "timestamp": "2026-05-22T12:34:56Z", "data": { "domain_id": "dom-uuid-...", "domain_name": "mysite.com", "registered_at": "2026-05-22T12:34:56Z", "expires_at": "2027-05-22T12:34:56Z", "cloudflare_enabled": true } } ``` ### Регистрация домена не удалась **`domain.failed`** Поле error содержит человекочитаемое объяснение. Сумма возвращается на баланс. Можно перевыбрать другое имя и оформить заказ заново. ```json { "event_type": "domain.failed", "timestamp": "2026-05-22T12:34:56Z", "data": { "domain_id": "dom-uuid-...", "domain_name": "mysite.com", "error": "Domain is no longer available" } } ``` ### Домен скоро истечёт **`domain.expires_soon`** Удобно, если авто-продление выключено: успеваете продлить вручную до того, как домен уйдёт в редемпшен. Флаг auto_renew подскажет, нужно ли вмешиваться. ```json { "event_type": "domain.expires_soon", "timestamp": "2026-05-22T12:34:56Z", "data": { "domain_id": "dom-uuid-...", "domain_name": "mysite.com", "expires_at": "2026-05-29T00:00:00Z", "auto_renew": false } } ``` ### Вайт сгенерирован **`white.completed`** Архив доступен через GET /whites/{id}/download. Если у вайта был указан домен, sitemap и контакты уже подставлены под него — можно сразу деплоить. ```json { "event_type": "white.completed", "timestamp": "2026-05-22T12:34:56Z", "data": { "job_id": "job-uuid-...", "name": "My White", "tier_key": "t1", "country": "DE" } } ``` ### Генерация вайта не удалась **`white.failed`** Поле error объясняет причину. Можно сразу запустить новую задачу через POST /whites — без потерь. ```json { "event_type": "white.failed", "timestamp": "2026-05-22T12:34:56Z", "data": { "job_id": "job-uuid-...", "name": "My White", "error": "Generation failed" } } ``` ## Коды ошибок Все ошибки возвращаются в одном формате: HTTP-статус + поле `error.code` + человеческое сообщение в `error.message`. ```json { "success": false, "error": { "code": "INSUFFICIENT_BALANCE", "message": "Not enough balance: required $5.00, available $1.20" } } ``` | Код | HTTP | Когда срабатывает | | --- | --- | --- | | `UNAUTHORIZED` | 401 | Ключ отсутствует, истёк или отозван. | | `INSUFFICIENT_PERMISSIONS` | 403 | У ключа нет нужного скоупа для этого действия. | | `PERMISSION_DENIED` | 403 | Аккаунт-уровень доступа не позволяет действие (например выкл. функция). | | `VALIDATION_ERROR` | 400 | Невалидное тело запроса. Сообщение объясняет, какое поле и почему. | | `NUMBER_NOT_FOUND` | 404 | Номер не существует или не принадлежит аккаунту. | | `NUMBER_EXPIRED` | 403 | Номер истёк — нужно Restore (в 7-дневное окно) или новая покупка. | | `NUMBER_NOT_ACTIVE` | 400 | Номер в статусе, не разрешающем эту операцию. | | `INSUFFICIENT_BALANCE` | 402 | Не хватает средств для операции. | | `INVALID_MESSAGE_FORMAT` | 400 | Тело SMS слишком длинное или содержит запрещённые символы. | | `COUNTRY_NOT_AVAILABLE` | 400 | Страна недоступна для покупки или продления. | | `NO_NUMBERS_AVAILABLE` | 400 | В выбранной стране сейчас нет свободных номеров. | | `NO_RESTORABLE_NUMBERS` | 404 | Все переданные номера уже невозможно восстановить. | | `RATE_LIMITED` | 429 | Превышен rate limit. Ждите время из заголовка `Retry-After`. | | `INTERNAL_ERROR` | 500 | Что-то пошло не так у нас. Если повторяется — пишите в саппорт. |