# piv.day API Reference Full reference for the piv.day REST API: every endpoint, request body, response shape, error code and webhook. Exported from https://piv.day/api/docs for use with AI assistants. --- ## Getting started 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. Усі ціни є підсумковими з урахуванням знижки вашої підписки. **Response fields** | Field | Type | Description | | --- | --- | --- | | `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 parameters** | Field | Type | Description | | --- | --- | --- | | `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-напрямки. **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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`, який далі використовується у всіх операціях з номером. **Request body** | Field | Type | Description | | --- | --- | --- | | `country_code` * | string | ISO-код країни. | | `duration_months` * | integer | Термін оренди в місяцях (мінімум 1). | | `auto_renew` * | boolean | Увімкнути авто-продовження одразу після купівлі. | | `custom_name` | string | Необов'язкове людинозрозуміле ім'я для номера. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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` Продовження активного номера на вказаний термін. Вартість списується з балансу в момент виклику. **Request body** | Field | Type | Description | | --- | --- | --- | | `duration_months` * | integer | На скільки місяців продовжити. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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}` Наразі редагується лише кастомне ім'я номера. **Request body** | Field | Type | Description | | --- | --- | --- | | `custom_name` * | string | Нове ім'я номера. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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 днів. **Request body** | Field | Type | Description | | --- | --- | --- | | `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`; за невдалі — гроші автоматично повертаються на баланс. **Request body** | Field | Type | Description | | --- | --- | --- | | `piv_num_ids` * | string[] | Масив ID номерів для відновлення. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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 parameters** | Field | Type | Description | | --- | --- | --- | | `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). Вартість повідомлення списується з балансу в момент відправки. **Request body** | Field | Type | Description | | --- | --- | --- | | `to_number` * | string | Номер отримувача в міжнародному форматі (E.164). | | `message_body` * | string | Текст повідомлення. Підтримуються GSM-7 і UCS-2. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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. Вартість списується з балансу в момент запуску. **Request body** | Field | Type | Description | | --- | --- | --- | | `gv_url` * | string | Повний URL Google-верифікації (береться зі сторінки Google). | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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 parameters** | Field | Type | Description | | --- | --- | --- | | `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-замовлень немає — за потреби викликайте метод повторно. **Request body** | Field | Type | Description | | --- | --- | --- | | `server_id` * | string | ID сервера з `GET /proxy/servers`. | | `quantity` * | integer | Скільки проксі купити (1–500). | | `months` * | integer | Термін оренди в місяцях (1–12). | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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` Продовжити активне замовлення проксі на додаткову кількість місяців. **Request body** | Field | Type | Description | | --- | --- | --- | | `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 parameters** | Field | Type | Description | | --- | --- | --- | | `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 parameters** | Field | Type | Description | | --- | --- | --- | | `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 parameters** | Field | Type | Description | | --- | --- | --- | | `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 ми ніколи не розкриваємо. **Request body** | Field | Type | Description | | --- | --- | --- | | `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`. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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` для відстеження. **Request body** | Field | Type | Description | | --- | --- | --- | | `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` Увімкнути або вимкнути автоматичне продовження домену. **Request body** | Field | Type | Description | | --- | --- | --- | | `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-запис. **Request body** | Field | Type | Description | | --- | --- | --- | | `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 parameters** | Field | Type | Description | | --- | --- | --- | | `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}`. **Request body** | Field | Type | Description | | --- | --- | --- | | `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. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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 parameters** | Field | Type | Description | | --- | --- | --- | | `format` | string | Формат архіву. За замовчуванням `php`. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `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" }' ``` ## Webhooks На ваш 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": { ... } } ``` **Retries.** При не-2xx або таймауті — до 3 повторних спроб із затримкою 1 с, 2 с, 4 с. Повна історія доставок доступна на сторінці API-ключів у дашборді. Якщо всі три не пройшли — подія позначається як failed, можна повторно надіслати вручну. **Security.** Використовуйте HTTPS-ендпойнт. Кожен запит надходить із заголовком `User-Agent: piv.day-webhook/1.0`. URL для вебхуків налаштовується в профілі API-ключа. ### All events | Event | When it fires | | --- | --- | | `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" } } ``` ## Error codes Усі помилки повертаються в одному форматі: HTTP-статус + поле `error.code` + зрозуміле повідомлення в `error.message`. ```json { "success": false, "error": { "code": "INSUFFICIENT_BALANCE", "message": "Not enough balance: required $5.00, available $1.20" } } ``` | Code | HTTP | When it fires | | --- | --- | --- | | `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 | Щось пішло не так з нашого боку. Якщо повторюється — зверніться до служби підтримки. |