Документация

Начало работы

REST API на Business-тарифе. Bearer-токены, JSON, идемпотентные эндпойнты, предсказуемые коды ошибок. Документация ниже описывает каждый эндпойнт с примером запроса и ответа.

Base URL

https://app.piv.day/api/v1

Все эндпойнты живут под этим префиксом. Окружение одно — отдельных staging-доменов нет.

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

Authorization: Bearer YOUR_API_KEY

Ключи создаются в дашборде в разделе Настройки → API Keys. У каждого ключа — гранулярные разрешения (чтение номеров, отправка SMS, покупка прокси и т.д.). Скомпрометированный токен ротируется в один клик без перерегистрации команды.

Аккаунт

GET/api/v1/account
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_codestringДвухбуквенный ISO-код страны (например SE).
price_per_monthnumberИтоговая цена для вашего тарифа — то, что реально спишется при покупке. Если у вас Premium или Business, скидка уже включена.
base_pricenumberЦена без скидок (Free-тариф). Возвращается для сравнения — увидеть, сколько экономит подписка.
can_send_smsbooleanМожно ли с этого номера отправлять исходящие SMS.
can_receive_smsbooleanМожно ли принимать входящие SMS.
sms_send_pricenumber|nullЦена за исходящее SMS — тоже с учётом тарифа. null, если отправка из этой страны недоступна.
GET/api/v1/numbers/countries
curl https://app.piv.day/api/v1/numbers/countries \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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-параметры

ПолеТипОписание
limitintegerРазмер страницы. По умолчанию 100, максимум 100.
offsetintegerСмещение для пагинации.
countrystringISO-код страны для фильтра.
statusstringОдин из active, expired, cancelled, pending.
searchstringПодстрока для поиска по номеру или кастомному имени.
GET/api/v1/numbers
curl "https://app.piv.day/api/v1/numbers?country=SE&status=active&limit=10" \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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_FOUND404Номер не найден или не принадлежит аккаунту.
GET/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o
curl https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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*stringISO-код страны.
duration_months*integerСрок аренды в месяцах (минимум 1).
auto_renew*booleanВключить ли авто-продление сразу после покупки.
custom_namestringОпциональное человекочитаемое имя для номера.

Ошибки

КодHTTPКогда срабатывает
COUNTRY_NOT_AVAILABLE400Страна недоступна или для неё нет цен.
NO_NUMBERS_AVAILABLE400В указанной стране сейчас нет свободных номеров.
INSUFFICIENT_BALANCE402На балансе не хватает средств для покупки.
VALIDATION_ERROR400Невалидные поля в теле запроса.
POST/api/v1/numbers/purchase
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"
  }'
200OK
{
  "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_FOUND404Номер не найден или не принадлежит аккаунту.
COUNTRY_NOT_AVAILABLE400Для страны номера не найдены цены.
INSUFFICIENT_BALANCE402Не хватает средств для продления.
POST/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/renew
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 }'
200OK
{
  "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_FOUND404Номер не найден или не принадлежит аккаунту.
VALIDATION_ERROR400Невалидное значение в теле запроса.
PATCH/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o
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" }'
200OK
{
  "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Новое значение флага авто-продления.
PATCH/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/auto-renewal
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 }'
200OK
{
  "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_NUMBERS404Ни один из переданных номеров нельзя восстановить (истёк 7-дневный срок или номер не ваш).
INSUFFICIENT_BALANCE402Не хватает средств на оплату восстановления.
POST/api/v1/numbers/restore
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"
    ]
  }'
200OK
{
  "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-параметры

ПолеТипОписание
limitintegerСколько сообщений вернуть. По умолчанию 100, максимум 100.
offsetintegerСмещение для пагинации.
GET/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/sms
curl "https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/sms?limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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_FOUND404Номер не найден или не принадлежит аккаунту.
NUMBER_EXPIRED403Номер уже истёк.
NUMBER_NOT_ACTIVE400Номер сейчас в состоянии, не разрешающем отправку.
INSUFFICIENT_BALANCE402Не хватает средств для отправки.
INVALID_MESSAGE_FORMAT400Тело сообщения превышает допустимую длину или содержит запрещённые символы.
POST/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/sms/send
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"
  }'
200OK
{
  "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. Стоимость списывается с баланса в момент запуска.

Тело запроса

ПолеТипОписание
target_url*stringПолный URL Google-верификации аккаунта. Должен начинаться с https://accounts.google.com.
proxy*stringСтрока подключения к прокси для задачи автоматизации. Любой формат, который принимает автоматизационный сервер (например socks5://user:pass@host:port).

Ошибки

КодHTTPКогда срабатывает
VALIDATION_ERROR400Некорректное тело запроса (нет target_url/proxy или URL не начинается с accounts.google.com).
INSUFFICIENT_PERMISSIONS403У API-ключа нет разрешения can_send_sms / can_run_verifications.
PERMISSION_DENIED403У участника команды нет разрешения verification.run или sms.send.
NUMBER_NOT_FOUND404Номер не найден или не ваш.
NUMBER_NOT_ACTIVE400Номер не в активном статусе.
SMS_DISABLED400Отправка SMS отключена для этого номера.
INSUFFICIENT_BALANCE402Не хватает средств для верификации.
PROXY_DEAD502Прокси недоступен — баланс возвращён.
QUEUE_FULL503Сервер занят, попробуйте позже — баланс возвращён.
SERVER_UNAVAILABLE503Сервер автоматизации недоступен — баланс возвращён.
GO_SERVER_ERROR503Автоматизационный сервер вернул неожиданную ошибку. Списание возвращено на баланс.
INTERNAL_ERROR500Внутренняя ошибка.
POST/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/verify
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 '{
    "target_url": "https://accounts.google.com/signin/v2/challenge/...",
    "proxy": "socks5://user:[email protected]:1080"
  }'
202Accepted
{
  "success": true,
  "message": "Verification initiated"
}
Документация

Прокси

Резидентский IPv6 в десятках стран. Покупка партиями, продление, Restore с теми же логином и паролем, экспорт в нужном формате.

Список серверов

GET/api/v1/proxy/servers

Список доступных прокси-серверов с ценами.

GET/api/v1/proxy/servers
curl https://app.piv.day/api/v1/proxy/servers \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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-параметры

ПолеТипОписание
limitintegerРазмер страницы. По умолчанию 100, максимум 100.
offsetintegerСмещение для пагинации.
statusstringФильтр статуса: active, expired, cancelled.
searchstringПоиск по заказу.
GET/api/v1/proxy/orders
curl "https://app.piv.day/api/v1/proxy/orders?status=active&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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}

Получить детали конкретного заказа, включая список прокси-учётных данных.

GET/api/v1/proxy/orders/ord-uuid-...
curl https://app.piv.day/api/v1/proxy/orders/ord-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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*stringID сервера из GET /proxy/servers.
quantity*integerСколько прокси купить (1–500).
months*integerСрок аренды в месяцах (1–12).

Ошибки

КодHTTPКогда срабатывает
PERMISSION_DENIED403У API-ключа или участника команды нет разрешения proxy.purchase.
INSUFFICIENT_BALANCE402Не хватает средств.
NOT_FOUND404Прокси-сервер не найден или неактивен.
VALIDATION_ERROR400Некорректное тело запроса.
PURCHASE_FAILED503Не удалось связаться с прокси-сервером или не удалось создать прокси.
INTERNAL_ERROR500Внутренняя ошибка.
POST/api/v1/proxy/purchase
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
  }'
200OK
{
  "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Сколько месяцев добавить.
POST/api/v1/proxy/orders/ord-uuid-.../renew
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 }'
200OK
{
  "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 месяц. Антидетект перенастраивать не надо.

Ошибки

КодHTTPКогда срабатывает
NOT_FOUND404Заказ или прокси-сервер не найден.
VALIDATION_ERROR400Восстановить можно только заказы со статусом expired.
PURCHASE_FAILED503Не удалось связаться с прокси-сервером или восстановить прокси.
INTERNAL_ERROR500Внутренняя ошибка.
POST/api/v1/proxy/orders/ord-uuid-.../restore
curl -X POST https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../restore \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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-параметры

ПолеТипОписание
formatstringФормат экспорта: socks5, http или both (по умолчанию socks5).
GET/api/v1/proxy/orders/ord-uuid-.../export
curl "https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../export?format=socks5" \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "success": true,
  "data": {
    "content": "user1:[email protected]:1080\nuser2:[email protected]:1080",
    "filename": "piv-day-proxy-ord-uuid--socks5.txt",
    "format": "socks5",
    "count": 2
  }
}
Документация

Домены

Поиск и регистрация без KYC, автоматический Cloudflare и SSL, управление DNS-записями и NS-серверами через API.

Список доменов

GET/api/v1/domains

Список ваших зарегистрированных доменов с возможностью фильтрации.

Query-параметры

ПолеТипОписание
limitintegerРазмер страницы. По умолчанию 100, максимум 100.
offsetintegerСмещение для пагинации.
statusstringСтатус домена: active, pending, expired, failed, cancelled.
cloudflarestringФильтр по статусу Cloudflare: true или false.
auto_renewstringФильтр по автопродлению: true или false.
searchstringПоиск по доменному имени.
GET/api/v1/domains
curl "https://app.piv.day/api/v1/domains?status=active&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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_modestringflexible | full | strict. Только при cloudflare: true.
nameserversstring[]Обязательно при cloudflare: false (≥2 NS). Запрещено при cloudflare: true.
dns_recordsobject[]Начальные DNS-записи. Только при cloudflare: true.

Ошибки

КодHTTPКогда срабатывает
PERMISSION_DENIED403У API-ключа или участника команды нет разрешения domains.purchase.
DOMAIN_NOT_AVAILABLE400Домен недоступен для регистрации.
INSUFFICIENT_BALANCE402Не хватает средств.
VALIDATION_ERROR400Некорректное тело запроса.
INTERNAL_ERROR500Внутренняя ошибка.
POST/api/v1/domains
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 }
    ]
  }'
POST/api/v1/domains
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"]
  }'
202Accepted
{
  "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} не нужен.

GET/api/v1/domains/queue/que-uuid-...
curl https://app.piv.day/api/v1/domains/queue/que-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY"
pending / processing
{
  "success": true,
  "data": {
    "queue_id": "que-uuid-...",
    "domain": "mysite.com",
    "status": "pending"
  }
}
completed — полная карточка
{
  "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.

GET/api/v1/domains/dom-uuid-...
curl https://app.piv.day/api/v1/domains/dom-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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 для отслеживания. Поле expires_at в ответе — текущая дата регистрации; финальная дата после продления приходит через webhook domain.expires_soon.

Тело запроса

ПолеТипОписание
period*integerНа сколько лет продлить.

Ошибки

КодHTTPКогда срабатывает
NOT_FOUND404Домен не найден.
VALIDATION_ERROR400Некорректное тело запроса.
DOMAIN_NOT_REGISTERED400Домен ещё не зарегистрирован у провайдера.
DOMAIN_NOT_ACTIVE400Продлевать можно только активные домены.
INTERNAL_ERROR500Внутренняя ошибка.
POST/api/v1/domains/dom-uuid-.../renew
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 }'
202Accepted
{
  "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Новое значение флага.
POST/api/v1/domains/dom-uuid-.../auto-renew
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 }'
200OK
{
  "success": true,
  "data": {
    "id": "dom-uuid-...",
    "auto_renew": true
  }
}

DNS-записи домена

GET/api/v1/domains/{id}/dns

Список DNS-записей домена (через Cloudflare).

GET/api/v1/domains/dom-uuid-.../dns
curl https://app.piv.day/api/v1/domains/dom-uuid-.../dns \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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Значение записи.
ttlintegerTTL в секундах (1 = авто).
priorityintegerПриоритет для MX/SRV-записей. Необязательный; игнорируется для типов, где не применим.
proxiedbooleanПроксировать через Cloudflare.
POST/api/v1/domains/dom-uuid-.../dns
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
  }'
201Created
{
  "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. Перезаписываются только переданные поля.

PUT/api/v1/domains/dom-uuid-.../dns/rec-uuid-...
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.

DELETE/api/v1/domains/dom-uuid-.../dns/rec-uuid-...
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 через этот эндпоинт не поддерживается.

Тело запроса

ПолеТипОписание
enabled*booleantrue — включить Cloudflare для домена. false этим эндпоинтом не поддерживается.
ssl_modestringРежим SSL: flexible, full, strict. По умолчанию flexible.

Ошибки

КодHTTPКогда срабатывает
NOT_FOUND404Домен не найден.
VALIDATION_ERROR400Некорректное тело запроса.
NOT_SUPPORTED400Отключение Cloudflare через этот эндпоинт не поддерживается.
ALREADY_ENABLED400Cloudflare уже включён для домена.
DOMAIN_NOT_REGISTERED400Домен ещё не зарегистрирован у провайдера.
CF_ZONE_LOOKUP_FAILED500Зона существует в Cloudflare, но получить её не удалось.
CF_ZONE_CREATE_FAILED500Не удалось создать зону в Cloudflare.
OP_NS_UPDATE_FAILED500Не удалось обновить nameservers у регистратора.
DB_UPDATE_FAILED500Не удалось сохранить изменения в базе.
INTERNAL_ERROR500Внутренняя ошибка.
POST/api/v1/domains/dom-uuid-.../cloudflare
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 }'
200OK
{
  "success": true,
  "data": {
    "domain_id": "dom-uuid-...",
    "ssl_mode": "flexible"
  }
}

Сменить NS-серверы

POST/api/v1/domains/{id}/ns-servers

Задать произвольные NS-серверы для домена.

Тело запроса

ПолеТипОписание
nameservers*string[]Список nameservers. Максимум 12 записей.
POST/api/v1/domains/dom-uuid-.../ns-servers
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"] }'
200OK
{
  "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.

GET/api/v1/whites/tiers
curl https://app.piv.day/api/v1/whites/tiers \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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-параметры

ПолеТипОписание
limitintegerРазмер страницы. По умолчанию 100, максимум 100.
offsetintegerСмещение для пагинации.
statusstringqueued | processing | done | failed.
tier_keystringv2_tier1 | v2_tier2 | v2_tier3.
GET/api/v1/whites
curl "https://app.piv.day/api/v1/whites?status=done&limit=20" \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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*stringv2_tier1 | v2_tier2 | v2_tier3.
niche*stringНиша сайта. Значения длиннее 25 символов молча обрезаются.
country*stringКод страны (ISO 3166-1 alpha-2).
language*stringОсновной язык сайта (ISO 639-1).
qualitystringstandard | premium (по умолчанию standard).
languagesstring[]Список языков. Первый включён в цену, каждый следующий — доплата.
domainstringПолный домен (напр. example.com). Без автоподстановки.
emailstringПолный email (напр. [email protected]). Без автоподстановки.
phonestringТелефон контакта.
addressstringАдрес компании.
legal_namestringЮридическое название.
style_hintstringСтиль дизайна. Один из: Random, Минималистичный, Корпоративный, Современный, Элегантный, Технологичный, Креативный, Профессиональный, Стартап стиль, Премиум, Динамичный, Классический, Футуристичный, Дружелюбный, Строгий, Яркий, Нейтральный, Градиентный, Монохромный, Контрастный, Светлый. Любое иное значение молча заменяется на Random.
keywordsstring[]Ключевые слова для SEO.
banned_wordsstring[]Слова, запрещённые в контенте.
blog_countintegerКол-во статей блога 3–20. Только для v2_tier3. За статьи сверх 3 — доплата.
generator_versionstringПереопределение версии генератора. Продвинутый параметр, обычно не нужен.
facebookstringПолный URL страницы Facebook.
instagramstringПолный URL профиля Instagram.
linkedinstringПолный URL профиля LinkedIn.
youtubestringПолный URL канала YouTube.
tiktokstringПолный URL профиля TikTok.

Ошибки

КодHTTPКогда срабатывает
PERMISSION_DENIED403У API-ключа или участника команды нет разрешения whites.purchase.
INSUFFICIENT_BALANCE402Не хватает средств.
INVALID_TIER400Тариф с таким ключом не найден.
VALIDATION_ERROR400Некорректное тело запроса.
INTERNAL_ERROR500Внутренняя ошибка.
POST/api/v1/whites
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": "[email protected]",
    "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,
    "facebook": "https://facebook.com/techblogde",
    "instagram": "https://instagram.com/techblogde",
    "linkedin": "https://linkedin.com/company/techblogde"
  }'
200OK
{
  "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}

Получить текущее состояние задачи генерации.

GET/api/v1/whites/job-uuid-...
curl https://app.piv.day/api/v1/whites/job-uuid-... \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "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-параметры

ПолеТипОписание
formatstringФормат архива. По умолчанию php.

Ошибки

КодHTTPКогда срабатывает
NOT_READY409Вайт ещё генерируется — повтори запрос после white.completed.
GET/api/v1/whites/job-uuid-.../download
curl "https://app.piv.day/api/v1/whites/job-uuid-.../download?format=php" \
  -H "Authorization: Bearer YOUR_API_KEY"
200OK
{
  "success": true,
  "data": {
    "url": "https://strg.piv.day/download/<user_id>/<job_id>?format=php&token=<hmac>&filename=<name>.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

Обновить контактные данные компании в вайт-странице без повторной генерации.

POST/api/v1/whites/job-uuid-.../config
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": "[email protected]",
    "phone": "+49 30 123456",
    "address": "Berliner Str. 1, Berlin",
    "legal": "My Brand GmbH"
  }'
Документация

Вебхуки

Подписка на события платформы: входящие SMS, готовые сайты, истекающие заказы. URL для уведомлений задаётся в настройках API-ключа.

Как они приходят

На ваш URL отправляется обычный POST с JSON-телом. Формат одинаковый для всех событий: event_type, timestamp и блок data. Ваш сервер должен ответить любым 2xx за 5 секунд.

Если не дошло

При не-2xx или таймауте — до 3 повторов с задержкой 1 с, 2 с, 4 с. История всех попыток доступна на странице API-ключей в дашборде. Если все три не прошли — событие отмечается как failed, можно переотправить вручную.

Безопасность

Используйте HTTPS-эндпойнт. Каждый запрос приходит с заголовком User-Agent: piv.day-webhook/1.0. URL для вебхуков настраивается в профиле API-ключа.

формат запроса
POST <your webhook URL>
Content-Type: application/json
User-Agent: piv.day-webhook/1.0

{
  "event_type": "<event identifier>",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": { ... }
}

Все события

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

payload
{
  "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 приходят код и текст ошибки от оператора.

payload
{
  "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. Удобно для скриптов: понятно, что просить заново.

payload
{
  "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.

payload
{
  "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. Сумма за неуспешную верификацию возвращается на баланс автоматически.

payload
{
  "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.

payload
{
  "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-записи или раскатывать сайт.

payload
{
  "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 содержит человекочитаемое объяснение. Сумма возвращается на баланс. Можно перевыбрать другое имя и оформить заказ заново.

payload
{
  "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 подскажет, нужно ли вмешиваться.

payload
{
  "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 и контакты уже подставлены под него — можно сразу деплоить.

payload
{
  "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 — без потерь.

payload
{
  "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.

КодHTTPКогда срабатывает
UNAUTHORIZED401Ключ отсутствует, истёк или отозван.
INSUFFICIENT_PERMISSIONS403У ключа нет нужного скоупа для этого действия.
PERMISSION_DENIED403Аккаунт-уровень доступа не позволяет действие (например выкл. функция).
VALIDATION_ERROR400Невалидное тело запроса. Сообщение объясняет, какое поле и почему.
NUMBER_NOT_FOUND404Номер не существует или не принадлежит аккаунту.
NUMBER_EXPIRED403Номер истёк — нужно Restore (в 7-дневное окно) или новая покупка.
NUMBER_NOT_ACTIVE400Номер в статусе, не разрешающем эту операцию.
INSUFFICIENT_BALANCE402Не хватает средств для операции.
INVALID_MESSAGE_FORMAT400Тело SMS слишком длинное или содержит запрещённые символы.
COUNTRY_NOT_AVAILABLE400Страна недоступна для покупки или продления.
NO_NUMBERS_AVAILABLE400В выбранной стране сейчас нет свободных номеров.
NO_RESTORABLE_NUMBERS404Все переданные номера уже невозможно восстановить.
RATE_LIMITED429Превышен rate limit. Ждите время из заголовка Retry-After.
INTERNAL_ERROR500Что-то пошло не так у нас. Если повторяется — пишите в саппорт.
Пример ошибки
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Not enough balance: required $5.00, available $1.20"
  }
}

Нашли неточность или нужен эндпойнт, которого нет в документации? Поддержка отвечает в Telegram в течение часа в рабочее время.

Связаться
Документация API — номера, домены, прокси, вайты | piv.day