Dokumentacja

Pierwsze kroki

REST API w planie Business. Tokeny Bearer, JSON, idempotentne endpointy, przewidywalne kody błędów. Każdy endpoint zawiera przykład żądania i odpowiedzi.

Base URL

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

Wszystkie endpointy znajdują się pod tym prefiksem. Jedno środowisko — brak oddzielnych hostów staging.

Uwierzytelnianie

Authorization: Bearer YOUR_API_KEY

Klucze są tworzone w dashboardzie w sekcji Ustawienia → API Keys. Każdy klucz ma szczegółowe uprawnienia (odczyt numerów, wysyłanie SMS, kupowanie proxy itp.). Skompromitowany token rotuje się jednym kliknięciem — bez ponownego onboardingu zespołu.

Konto

GET/api/v1/account
curl https://app.piv.day/api/v1/account \
  -H "Authorization: Bearer YOUR_API_KEY"
Jeden pomocniczy endpoint — saldo i email bieżącego konta. Wygodne do sprawdzenia, czy klucz działa i uwierzytelnianie jest poprawnie skonfigurowane.
{
  "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

Format odpowiedzi

{
  "success": true,
  "data": { ... }
}

Wszystkie odpowiedzi są w formacie JSON. W przypadku błędu success = false, a ciało zawiera error.code i error.message.

Rate limits

100 żądań na minutę na klucz API. Limit jest wspólny dla wszystkich endpointów. Potrzebujesz większego limitu pod obciążenie? Napisz do wsparcia Telegram, a podniesiemy limit bez zbędnych formalności. Po przekroczeniu limitu otrzymasz `429 RATE_LIMITED` i nagłówek `Retry-After` — ile sekund czekać przed kolejnym żądaniem.
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

Dokumentacja

Numery

Kupuj, odnawiaj i przywracaj numery. Odbieraj i wysyłaj SMS. Uruchamiaj weryfikacje Google QR. Subskrybuj zdarzenia przez webhooki.

Kraje i ceny

GET/api/v1/numbers/countries

Zwraca kraje dostępne do zakupu z aktualną ceną i możliwościami SMS. Wszystkie ceny uwzględniają zniżkę z subskrypcji.

Pola odpowiedzi

PoleTypOpis
country_codestringDwuliterowy kod kraju ISO (np. SE).
price_per_monthnumberOstateczna cena dla Twojego planu — to, co zostanie naliczone przy zakupie. Zniżki Premium / Business są już uwzględnione.
base_pricenumberCena bez rabatów (plan Free). Zwracana w celu porównania — żeby zobaczyć, ile oszczędza subskrypcja.
can_send_smsbooleanCzy z tego numeru można wysyłać wychodzące SMS.
can_receive_smsbooleanCzy przychodzące SMS są obsługiwane.
sms_send_pricenumber|nullCena za wychodzący SMS, również z rabatem planu. null, gdy wysyłanie z tego kraju nie jest obsługiwane.
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
    }
  ]
}

Lista numerów konta

GET/api/v1/numbers

Zwraca stronę numerów konta z filtrami według kraju, statusu i wyszukiwaniem po numerze lub niestandardowej nazwie.

Parametry zapytania

PoleTypOpis
limitintegerRozmiar strony (domyślnie 50, maksymalnie 200).
offsetintegerPrzesunięcie paginacji.
countrystringFiltr kodu kraju ISO.
statusstringJeden z: active, expired, pending_restore.
searchstringWyszukiwanie podciągu po numerze telefonu lub niestandardowej nazwie.
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 }
  }
}

Jeden numer po ID

GET/api/v1/numbers/{piv_num_id}

Pełna karta numeru: status, daty, auto-odnowienie, tagi, dozwolone kierunki SMS.

Błędy

KodHTTPKiedy się aktywuje
NUMBER_NOT_FOUND404Numer nie istnieje lub nie należy do konta.
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
  }
}

Kup numer

POST/api/v1/numbers/purchase

Kupuje jeden numer w wybranym kraju na wskazany okres. Kwota jest pobierana z salda konta. Zwraca piv_num_id używane we wszystkich późniejszych operacjach na numerze.

Treść żądania

PoleTypOpis
country_code*stringKod kraju ISO.
duration_months*integerOkres wynajmu w miesiącach (minimum 1).
auto_renew*booleanWłączyć auto-odnowienie zaraz po zakupie.
custom_namestringOpcjonalna czytelna dla człowieka nazwa numeru.

Błędy

KodHTTPKiedy się aktywuje
COUNTRY_NOT_AVAILABLE400Kraj niedostępny lub brak cennika.
NO_NUMBERS_AVAILABLE400Brak dostępnych numerów w żądanym kraju w tej chwili.
INSUFFICIENT_BALANCE402Niewystarczające środki na saldzie.
VALIDATION_ERROR400Nieprawidłowe pola w treści żądania.
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"
    }
  ]
}

Odnów numer

POST/api/v1/numbers/{piv_num_id}/renew

Przedłuża aktywny numer na wskazany okres. Koszt jest pobierany w momencie wywołania.

Treść żądania

PoleTypOpis
duration_months*integerO ile miesięcy przedłużyć.

Błędy

KodHTTPKiedy się aktywuje
NUMBER_NOT_FOUND404Numer nie istnieje lub nie należy do konta.
COUNTRY_NOT_AVAILABLE400Nie znaleziono cen dla kraju numeru.
INSUFFICIENT_BALANCE402Niewystarczające środki na odnowienie.
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
  }
}

Zaktualizuj numer

PATCH/api/v1/numbers/{piv_num_id}

Obecnie można zaktualizować tylko niestandardową nazwę numeru.

Treść żądania

PoleTypOpis
custom_name*stringNowa nazwa numeru.

Błędy

KodHTTPKiedy się aktywuje
NUMBER_NOT_FOUND404Numer nie istnieje lub nie należy do konta.
VALIDATION_ERROR400Nieprawidłowa wartość w treści żądania.
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": []
  }
}

Zarządzanie auto-odnowieniem

PATCH/api/v1/numbers/{piv_num_id}/auto-renewal

Włącza lub wyłącza auto-odnowienie numeru. Gdy jest włączone, odnowienie jest pobierane automatycznie 24 godziny przed wygaśnięciem. Jeśli środki są niewystarczające, numer wygasa; można go odzyskać przez POST /numbers/restore w ciągu 7 dni.

Treść żądania

PoleTypOpis
auto_renew*booleanNowa wartość flagi auto-odnowienia.
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
  }
}

Przywróć wygasłe numery

POST/api/v1/numbers/restore

Odzyskuje wygasłe numery w ciągu 7-dniowego okna. Przekaż tablicę piv_num_id — numery wracają z zachowaną historią SMS i ustawieniami. Przywrócenie kosztuje więcej niż zakup nowego numeru (zawiera mnożnik przywracania) — dokładne liczby są widoczne w dashboardzie przed potwierdzeniem. Ostateczny status każdego numeru przychodzi przez webhook number.restore_completed; zwroty za nieudane numery są automatycznie dopisywane do salda.

Treść żądania

PoleTypOpis
piv_num_ids*string[]Tablica ID numerów do przywrócenia.

Błędy

KodHTTPKiedy się aktywuje
NO_RESTORABLE_NUMBERS404Żaden z przekazanych numerów nie może być przywrócony (upłynął 7-dniowy termin lub numery nie należą do Ciebie).
INSUFFICIENT_BALANCE402Niewystarczające środki na pokrycie przywrócenia.
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"
    }
  ]
}

Historia SMS numeru

GET/api/v1/numbers/{piv_num_id}/sms

Zwraca przychodzące i wychodzące wiadomości dla numeru w odwrotnym porządku chronologicznym.

Parametry zapytania

PoleTypOpis
limitintegerIle wiadomości zwrócić (domyślnie 50, maksymalnie 200).
offsetintegerPrzesunięcie paginacji.
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 }
  }
}

Wyślij SMS

POST/api/v1/numbers/{piv_num_id}/sms/send

Dostępne dla krajów, gdzie dozwolone jest wysyłanie wychodzące (np. CA, GB, SE). Koszt wiadomości jest pobierany w momencie wysyłania.

Treść żądania

PoleTypOpis
to_number*stringNumer odbiorcy w formacie międzynarodowym (E.164).
message_body*stringTreść wiadomości. Obsługiwane są GSM-7 i UCS-2.

Błędy

KodHTTPKiedy się aktywuje
NUMBER_NOT_FOUND404Numer nie istnieje lub nie należy do konta.
NUMBER_EXPIRED403Numer już wygasł.
NUMBER_NOT_ACTIVE400Numer jest w stanie, który nie pozwala na wysyłanie.
INSUFFICIENT_BALANCE402Niewystarczające środki na wysyłanie.
INVALID_MESSAGE_FORMAT400Treść wiadomości przekracza dozwoloną długość lub zawiera zabronione znaki.
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"
  }
}

Uruchom weryfikację Google QR

POST/api/v1/numbers/{piv_num_id}/verify

Uruchamia weryfikację Google QR przy użyciu podanego URL. Wynik — sukces lub błąd — przychodzi przez webhook verify.completed lub verify.failed. Koszt jest pobierany w momencie kolejkowania zadania.

Treść żądania

PoleTypOpis
gv_url*stringPełny URL weryfikacji Google (pobrany ze strony Google).

Błędy

KodHTTPKiedy się aktywuje
NUMBER_NOT_FOUND404Numer nie istnieje lub nie należy do Ciebie.
NUMBER_NOT_ACTIVE400Numer nie jest aktywny.
SMS_DISABLED400Wysyłanie SMS jest wyłączone dla tego numeru.
INSUFFICIENT_BALANCE402Niewystarczające środki na weryfikację.
PROXY_DEAD502Proxy niedostępne — saldo zwrócone.
QUEUE_FULL503Kolejka jest pełna, spróbuj później — saldo zwrócone.
SERVER_UNAVAILABLE503Serwer automatyzacji niedostępny — saldo zwrócone.
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 '{ "gv_url": "https://gv.google.com/..." }'
202Accepted
{
  "success": true,
  "message": "Verification initiated"
}
Dokumentacja

Proxy

Residential IPv6 w dziesiątkach krajów. Zakup hurtowy, odnowienie, Restore z tym samym loginem i hasłem, eksport w wybranym formacie.

Lista serwerów

GET/api/v1/proxy/servers

Dostępne serwery proxy z cenami.

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
      }
    ]
  }
}

Lista zamówień

GET/api/v1/proxy/orders

Lista Twoich zamówień proxy z możliwością filtrowania według statusu lub wyszukiwania.

Parametry zapytania

PoleTypOpis
limitintegerRozmiar strony. Domyślnie 100, maksymalnie 500.
offsetintegerPrzesunięcie paginacji.
statusstringFiltr statusu: active, expired.
searchstringWyszukiwanie w zamówieniach.
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 }
  }
}

Pobierz jedno zamówienie

GET/api/v1/proxy/orders/{id}

Pobierz szczegóły konkretnego zamówienia, w tym listę danych logowania proxy.

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"
        }
      ]
    }
  }
}

Kup proxy

POST/api/v1/proxy/purchase

Kup proxy na wybranym serwerze. Jedno żądanie tworzy jedno zamówienie z N proxy (do 500). Nie ma zamówień hurtowych — wywołaj metodę ponownie, jeśli potrzebujesz więcej.

Treść żądania

PoleTypOpis
server_id*stringID serwera z GET /proxy/servers.
quantity*integerIle proxy kupić (1–500).
months*integerOkres wynajmu w miesiącach (1–12).

Błędy

KodHTTPKiedy się aktywuje
INSUFFICIENT_BALANCE402Niewystarczające środki.
NOT_FOUND404Serwer proxy nie został znaleziony lub jest nieaktywny.
VALIDATION_ERROR400Nieprawidłowe ciało żądania.
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"
        }
      ]
    }
  }
}

Odnów zamówienie

POST/api/v1/proxy/orders/{id}/renew

Przedłuż aktywne zamówienie proxy o określoną liczbę miesięcy.

Treść żądania

PoleTypOpis
months*integerLiczba miesięcy do dodania.
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 wygasłego zamówienia

POST/api/v1/proxy/orders/{id}/restore

Przywróć wygasłe zamówienie proxy bez ponownego zakupu. Login, hasło, adresy IPv6, kraj i powiązania — te same. Termin przedłużany o 1 miesiąc. Nie ma potrzeby ponownej konfiguracji antidetect.

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"
  }
}

Eksportuj proxy

GET/api/v1/proxy/orders/{id}/export

Eksportuj dane logowania proxy zamówienia jako listę tekstową (login:password@host:port).

Parametry zapytania

PoleTypOpis
formatstringFormat eksportu: socks5, http lub both (domyślnie 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
  }
}
Dokumentacja

Domeny

Wyszukiwanie i rejestracja bez KYC, automatyczny Cloudflare i SSL, zarządzanie rekordami DNS i serwerami NS przez API.

Lista domen

GET/api/v1/domains

Lista zarejestrowanych domen z możliwością filtrowania.

Parametry zapytania

PoleTypOpis
limitintegerRozmiar strony. Domyślnie 100, maksimum 500.
offsetintegerPrzesunięcie dla paginacji.
statusstringStatus domeny: active, pending, expired.
cloudflarestringFiltruj według statusu Cloudflare: true lub false.
auto_renewstringFiltruj według automatycznego odnawiania: true lub false.
searchstringWyszukaj według nazwy domeny.
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 }
  }
}

Rejestracja domeny

POST/api/v1/domains

Zarejestrować nową domenę. Żądanie jest asynchroniczne — zwraca queue_id do śledzenia. Cloudflare WŁ: nie przekazywać nameservers; opcjonalnie można przekazać dns_records i ssl_mode. Cloudflare WYŁ: nie przekazywać dns_records ani ssl_mode; nameservers jest wymagany (co najmniej 2). Nigdy nie ujawniamy serwerów nazw Cloudflare.

Treść żądania

PoleTypOpis
domain*stringNazwa domeny do rejestracji, np. mysite.com.
period*integerOkres rejestracji w latach (1–10).
cloudflare*booleanAutomatycznie podłączyć domenę do Cloudflare.
auto_renew*booleanWłączyć automatyczne odnawianie.
ssl_modestringflexible | full | strict. Tylko przy cloudflare: true.
nameserversstring[]Wymagane przy cloudflare: false (≥2 NS). Zabronione przy cloudflare: true.
dns_recordsobject[]Początkowe rekordy DNS. Tylko przy cloudflare: true.

Błędy

KodHTTPKiedy się aktywuje
DOMAIN_NOT_AVAILABLE400Domena nie jest dostępna do rejestracji.
INSUFFICIENT_BALANCE402Niewystarczające środki.
VALIDATION_ERROR400Nieprawidłowe ciało żądania.
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"
    }
  }
}

Status zadania rejestracji

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

Sprawdzić status wpisu kolejki rejestracji lub odnawiania domeny. Przy statusie completed odpowiedź zawiera już pełną kartę domeny — osobne żądanie do /domains/{id} nie jest potrzebne.

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 — pełna karta
{
  "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 }
      ]
    }
  }
}

Pobierz jedną domenę

GET/api/v1/domains/{id}

Pobierz pełne informacje o zarejestrowanej domenie. Pole nameservers jest obecne tylko gdy 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 }
      ]
    }
  }
}

Odnów domenę

POST/api/v1/domains/{id}/renew

Odnowić rejestrację domeny. Zwraca queue_id do śledzenia.

Treść żądania

PoleTypOpis
period*integerO ile lat przedłużyć.
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"
  }
}

Przełącznik auto-odnawiania

POST/api/v1/domains/{id}/auto-renew

Włączyć lub wyłączyć automatyczne odnawianie domeny.

Treść żądania

PoleTypOpis
auto_renew*booleanNowa wartość flagi.
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
  }
}

Rekordy DNS domeny

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

Lista rekordów DNS domeny (przez 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
      }
    ]
  }
}

Dodaj rekord DNS

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

Utwórz nowy rekord DNS.

Treść żądania

PoleTypOpis
type*stringTyp rekordu: A, AAAA, CNAME, MX, TXT itp.
name*stringNazwa rekordu, np. @ lub subdomain.
content*stringWartość rekordu.
ttlintegerTTL w sekundach (1 = auto).
proxiedbooleanProxy przez 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
    }
  }
}

Zaktualizuj rekord DNS

PUT/api/v1/domains/{id}/dns/{recordId}

Zaktualizować istniejący rekord DNS po ID. Nadpisywane są tylko przekazane pola.

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" }'

Usuń rekord DNS

DELETE/api/v1/domains/{id}/dns/{recordId}

Usuń rekord DNS po 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"

Włącz Cloudflare

POST/api/v1/domains/{id}/cloudflare

Włączyć Cloudflare dla domeny. Nie zwracamy serwerów nazw Cloudflare — delegację konfigurujemy po naszej stronie. Wyłączanie Cloudflare przez ten endpoint nie jest obsługiwane.

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"
  }
}

Ustaw serwery nazw

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

Ustawić niestandardowe serwery nazw dla domeny.

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 }
    ]
  }
}
Dokumentacja

White'y

Generowanie white-page'ów według niszy i tiera. Każda strona jest unikalna. Zmiana domeny i kontaktów bez ponownej generacji.

Lista tierów

GET/api/v1/whites/tiers

Dostępne tiery generacji z cenami. price to cena za generację dopasowana do twojego konta (z uwzględnieniem subskrypcji), pojedyncza liczba. quality: "premium" kosztuje więcej (obliczane przy tworzeniu). Blog tylko w v2_tier3: pierwsze 3 artykuły są wliczone, każdy kolejny (do 20) jest naliczany jako 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
      }
    ]
  }
}

Lista white'ów

GET/api/v1/whites

Lista twoich zadań generacji z możliwością filtrowania.

Parametry zapytania

PoleTypOpis
limitintegerRozmiar strony. Domyślnie 100, maksymalnie 500.
offsetintegerOffset paginacji.
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 }
  }
}

Uruchom generację

POST/api/v1/whites

Dodaj zadanie generacji white-page do kolejki. Płatność jest pobierana natychmiast. Końcowy status trafia na webhook white.completed / white.failed lub można go sprawdzić przez GET /whites/{id}.

Treść żądania

PoleTypOpis
name*stringNazwa zadania (2–20 znaków).
tier_key*stringv2_tier1 | v2_tier2 | v2_tier3.
niche*stringNisza strony (do 25 znaków).
country*stringKod kraju (ISO 3166-1 alpha-2).
language*stringGłówny język strony (ISO 639-1).
qualitystringstandard | premium (domyślnie standard).
languagesstring[]Lista języków. Pierwszy jest wliczony w cenę; każdy dodatkowy kosztuje więcej.
domainstringPełna domena (np. example.com). Bez autouzupełniania.
emailstringPełny adres email (np. [email protected]). Bez autouzupełniania.
phonestringTelefon kontaktowy.
addressstringAdres firmy.
legal_namestringNazwa prawna.
style_hintstringStyl designu (Random, Minimalistyczny, Korporacyjny itd.).
keywordsstring[]Słowa kluczowe SEO.
banned_wordsstring[]Słowa zakazane w treści.
blog_countintegerLiczba artykułów bloga 3–20. Tylko dla v2_tier3. Artykuły powyżej 3 są dodatkowo płatne.
contacts_modestringsame | template.
contacts_templatestringSzablon strony kontaktowej (gdy contacts_mode=template).
facebookstringPełny URL strony Facebook.
instagramstringPełny URL profilu Instagram.
linkedinstringPełny URL profilu LinkedIn.
youtubestringPełny URL kanału YouTube.
tiktokstringPełny URL profilu TikTok.

Błędy

KodHTTPKiedy się aktywuje
INSUFFICIENT_BALANCE402Niewystarczające środki.
INVALID_TIER400Nie znaleziono tiera z takim kluczem.
VALIDATION_ERROR400Nieprawidłowe ciało żądania.
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,
    "contacts_mode": "same",
    "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"
    }
  }
}

Pobierz jeden white

GET/api/v1/whites/{id}

Pobierz bieżący stan zadania generacji.

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"
    }
  }
}

Pobierz archiwum

GET/api/v1/whites/{id}/download

Pobierz krótkotrwały podpisany link do gotowego archiwum white-page. Link jest ważny przez ~5 minut (patrz expires_at). Jeśli wygasł — ponownie wywołaj /download, a wystawimy nowy. Jeśli white page nie jest jeszcze wygenerowany, zwracany jest 409 NOT_READY.

Parametry zapytania

PoleTypOpis
formatstringFormat archiwum. Domyślnie php.

Błędy

KodHTTPKiedy się aktywuje
NOT_READY409White page jest jeszcze generowany — ponów żądanie po 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"
  }
}

Zmień domenę i kontakty

POST/api/v1/whites/{id}/config

Zaktualizuj dane kontaktowe firmy w white-page bez ponownej generacji.

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"
  }'
Dokumentacja

Webhooks

Subskrybuj zdarzenia platformy: przychodzące SMS, gotowe witryny, wygasające zamówienia. URL powiadomień ustawiasz w profilu klucza API.

Jak przychodzą

Na Twój URL wysyłamy zwykły POST z ciałem JSON. Format jest taki sam dla wszystkich zdarzeń: event_type, timestamp i blok data. Twój serwer powinien odpowiedzieć dowolnym 2xx w ciągu 5 sekund.

Gdy dostarczenie nie powiedzie się

W przypadku nie-2xx lub przekroczenia czasu — do 3 ponownych prób z opóźnieniem 1s / 2s / 4s. Pełna historia dostarczeń jest dostępna na stronie kluczy API w dashboardzie. Jeśli wszystkie trzy nie powiodą się — zdarzenie jest oznaczane jako failed i można je ponownie wysłać ręcznie.

Bezpieczeństwo

Używaj endpointu HTTPS. Każde żądanie przychodzi z nagłówkiem User-Agent: piv.day-webhook/1.0. URL webhooka jest konfigurowany w profilu klucza API.

format żądania
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": { ... }
}

Wszystkie zdarzenia

ZdarzenieKiedy się aktywuje
sms.receivedZaufany nadawca właśnie wysłał SMS na jeden z Twoich numerów.
sms.status_updatedWychodzący SMS zmienił status — np. został dostarczony lub nie powiódł się.
number.restore_completedWsadowy Restore dobiegł końca — tutaj trafia końcowe podsumowanie.
verify.completedWeryfikacja konta Google zakończyła się pomyślnie.
verify.failedCoś poszło nie tak — Google nie zaakceptował.
proxy.expires_soonDo końca zamówienia proxy pozostały około trzy dni.
domain.registeredZamówienie rejestracji zakończyło się pomyślnie — domena jest aktywna.
domain.failedZamówienie nie zostało zrealizowane — częsta przyczyna: nazwa właśnie została zajęta.
domain.expires_soonDo wygaśnięcia domeny pozostał około tydzień.
white.completedZadanie generowania White zakończyło się pomyślnie.
white.failedZadanie nie powiodło się — środki są zwracane na saldo.

Przychodzący SMS na Twój numer

sms.received

Najczęściej są to kody weryfikacyjne z sieci reklamowych. Payload zawiera zarówno surowy tekst, jak i automatycznie wykryty kod (jeśli jest) — możesz go od razu przekazać do swojego workflow bez parsowania. Wiadomości od znanych nadawców spamu nie są przekazywane.

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"
  }
}

Status wysłanego SMS-a się zmienił

sms.status_updated

Przydatne, gdy wysyłasz potwierdzenia z własnego numeru i chcesz wiedzieć, czy wiadomość dotarła. Jeśli status to failed — w payload przychodzą kod błędu i komunikat od operatora.

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
  }
}

Przywracanie numerów zakończone

number.restore_completed

Zawiera dwie listy: które numery wróciły i które nie. Zwrócona kwota za te, które nie wróciły, jest też w payload. Wygodne dla skryptów, które chcą inteligentnie ponowić próbę.

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
  }
}

Weryfikacja Google QR zakończona sukcesem

verify.completed

Jeśli podczas procesu przyszedł SMS z kodem — jest już tutaj, nie trzeba go osobno pobierać. Pola captured_phone i captured_message zawierają to, co wysłał 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"
  }
}

Weryfikacja Google QR nieudana

verify.failed

error_code mówi dokładnie co: timeout, odrzucenie, nieprawidłowy URL. Za nieudane weryfikacje kwota jest automatycznie zwracana na saldo.

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 wkrótce wygaśnie

proxy.expires_soon

Dla tych, którzy nie odnawiają automatycznie: widzisz to z wyprzedzeniem i decydujesz — przedłużyć czy zakończyć kampanię. Podepnij pod POST /proxy/orders/{id}/renew, aby odnawiać w pełni automatycznie.

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"
  }
}

Domena zarejestrowana

domain.registered

Jeśli przy zakupie zażądałeś Cloudflare i SSL, oba są już aktywne — flaga cloudflare_enabled pokazuje status. Możesz od razu dodawać rekordy DNS lub wdrożyć stronę.

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
  }
}

Rejestracja domeny nie powiodła się

domain.failed

Pole error zawiera czytelne dla człowieka wyjaśnienie. Kwota jest zwracana na saldo. Można wybrać inną nazwę i złożyć zamówienie ponownie.

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"
  }
}

Domena wkrótce wygaśnie

domain.expires_soon

Wygodne, gdy automatyczne odnawianie jest wyłączone: masz czas, aby odnowić ręcznie, zanim domena przejdzie w fazę redemption. Flaga auto_renew poinformuje, czy konieczna jest interwencja.

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 wygenerowany

white.completed

Archiwum jest dostępne przez GET /whites/{id}/download. Jeśli White miał ustawioną domenę, sitemap i kontakty są już pod nią skonfigurowane — gotowe do wdrożenia.

payload
{
  "event_type": "white.completed",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "job_id": "job-uuid-...",
    "name": "My White",
    "tier_key": "t1",
    "country": "DE"
  }
}

Generowanie White nieudane

white.failed

Pole error wyjaśnia przyczynę. Możesz od razu uruchomić nowe zadanie przez POST /whites — bez strat.

payload
{
  "event_type": "white.failed",
  "timestamp": "2026-05-22T12:34:56Z",
  "data": {
    "job_id": "job-uuid-...",
    "name": "My White",
    "error": "Generation failed"
  }
}
Dokumentacja referencyjna

Kody błędów

Wszystkie błędy mają ten sam format: status HTTP + pole error.code + czytelna wiadomość w error.message.

KodHTTPKiedy się aktywuje
UNAUTHORIZED401Klucz jest nieobecny, wygasł lub został odwołany.
INSUFFICIENT_PERMISSIONS403Klucz nie posiada wymaganego scope dla tej operacji.
PERMISSION_DENIED403Dostęp na poziomie konta nie zezwala na tę operację (np. funkcja wyłączona).
VALIDATION_ERROR400Nieprawidłowe ciało żądania. Wiadomość wyjaśnia, które pole jest błędne i dlaczego.
NUMBER_NOT_FOUND404Numer nie istnieje lub nie należy do tego konta.
NUMBER_EXPIRED403Numer wygasł — użyj Restore (w ciągu 7 dni) lub kup nowy.
NUMBER_NOT_ACTIVE400Numer jest w stanie, który nie zezwala na tę operację.
INSUFFICIENT_BALANCE402Niewystarczające środki do wykonania tej operacji.
INVALID_MESSAGE_FORMAT400Treść SMS jest zbyt długa lub zawiera niedozwolone znaki.
COUNTRY_NOT_AVAILABLE400Kraj jest niedostępny do zakupu lub odnowienia.
NO_NUMBERS_AVAILABLE400W wybranym kraju nie ma teraz dostępnych numerów.
NO_RESTORABLE_NUMBERS404Żaden z podanych numerów nie może być już przywrócony.
RATE_LIMITED429Przekroczono rate limit. Poczekaj czas podany w nagłówku Retry-After.
INTERNAL_ERROR500Coś poszło nie tak po naszej stronie. Jeśli problem się powtarza — skontaktuj się z pomocą techniczną.
Przykład błędu
{
  "success": false,
  "error": {
    "code": "INSUFFICIENT_BALANCE",
    "message": "Not enough balance: required $5.00, available $1.20"
  }
}

Znalazłeś błąd lub potrzebujesz endpointu, którego tu nie ma? Wsparcie odpowiada na Telegramie w ciągu godziny w godzinach roboczych.

Skontaktuj się z pomocą
piv.day Dokumentacja API — numery, domeny, proxy, white page'i