# piv.day API Reference Full reference for the piv.day REST API: every endpoint, request body, response shape, error code and webhook. Exported from https://piv.day/api/docs for use with AI assistants. --- ## Getting started REST API im Business-Tarif. Bearer-Tokens, JSON, idempotente Endpunkte, vorhersagbare Fehlercodes. Jeder Endpunkt enthält ein Anfrage- und Antwortbeispiel. ### Base URL ``` https://app.piv.day/api/v1 ``` Alle Endpunkte befinden sich unter diesem Präfix. Eine einzige Umgebung — keine separaten Staging-Hosts. ### Authentifizierung ``` Authorization: Bearer YOUR_API_KEY ``` Schlüssel werden im Dashboard unter `Einstellungen → API Keys` erstellt. Jeder Schlüssel hat feingranulare Berechtigungen (Nummern lesen, SMS senden, Proxies kaufen usw.). Ein kompromittierter Token wird mit einem Klick rotiert — kein erneutes Onboarding des Teams erforderlich. ### Konto **200 OK** ``` curl https://app.piv.day/api/v1/account \ -H "Authorization: Bearer YOUR_API_KEY" ``` **Ein einzelner Hilfs-Endpunkt — Kontostand und E-Mail des aktuellen Kontos. Praktisch zur Überprüfung, dass der Schlüssel funktioniert und die Authentifizierung korrekt eingerichtet ist.** ``` { "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 ### Antwortformat ``` { "success": true, "data": { ... } } ``` Alle Antworten sind JSON. Bei einem Fehler ist `success` = `false` und der Body enthält `error.code` und `error.message`. ### Rate limits **100 Anfragen pro Minute pro API-Schlüssel. Das Limit gilt übergreifend für alle Endpunkte. Benötigen Sie mehr Spielraum für einen Lastspike? Schreiben Sie dem Telegram-Support und wir erhöhen das Limit. Bei Überschreitung erhalten Sie `429 RATE_LIMITED` und den `Retry-After`-Header — wie viele Sekunden bis zur nächsten Anfrage gewartet werden soll.** ``` 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 ## Nummern Nummern kaufen, verlängern und wiederherstellen. SMS empfangen und senden. Google QR-Verifizierungen starten. Über Webhooks Ereignisse abonnieren. ### Länder und Preise `GET /api/v1/numbers/countries` Gibt zum Kauf verfügbare Länder mit aktuellem Preis und SMS-Funktionen zurück. Alle Preise beinhalten den Rabatt Ihres Abonnements. **Response fields** | Field | Type | Description | | --- | --- | --- | | `country_code` | string | Zweistelliger ISO-Ländercode (z. B. `SE`). | | `price_per_month` | number | Endpreis für Ihren Tarif — was tatsächlich beim Kauf berechnet wird. Premium / Business-Rabatte sind bereits eingerechnet. | | `base_price` | number | Preis ohne Rabatte (Free-Tarif). Wird zum Vergleich zurückgegeben, um zu sehen, wie viel das Abonnement spart. | | `can_send_sms` | boolean | Ob ausgehende SMS von dieser Nummer unterstützt werden. | | `can_receive_sms` | boolean | Ob eingehende SMS unterstützt werden. | | `sms_send_price` | number\|null | Preis für ausgehende SMS, ebenfalls mit dem Tarifrabatt. `null`, wenn das Senden aus diesem Land nicht unterstützt wird. | **curl** ```bash curl https://app.piv.day/api/v1/numbers/countries \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": [ { "country_code": "SE", "price_per_month": 4.00, "base_price": 5.00, "can_send_sms": true, "can_receive_sms": true, "sms_send_price": 0.25 }, { "country_code": "GB", "price_per_month": 3.00, "base_price": 3.00, "can_send_sms": true, "can_receive_sms": true, "sms_send_price": 0.20 } ] } ``` ### Nummernliste des Kontos `GET /api/v1/numbers` Gibt eine Seite der Kontonummern mit Filtern nach Land, Status und Suche nach Nummer oder benutzerdefiniertem Namen zurück. **Query parameters** | Field | Type | Description | | --- | --- | --- | | `limit` | integer | Seitengröße (Standard 50, maximal 200). | | `offset` | integer | Paginierungs-Offset. | | `country` | string | ISO-Ländercode-Filter. | | `status` | string | Einer von `active`, `expired`, `pending_restore`. | | `search` | string | Teilzeichenkettensuche nach Telefonnummer oder benutzerdefiniertem Namen. | **curl** ```bash curl "https://app.piv.day/api/v1/numbers?country=SE&status=active&limit=10" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "numbers": [ { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "country_code": "SE", "status": "active", "created_at": "2026-05-01T10:00:00Z", "expires_at": "2026-05-31T10:00:00Z", "auto_renew": false, "custom_name": "Office line", "purchased_at": "2026-05-01T10:00:00Z", "next_renewal_date": "2026-05-31T10:00:00Z", "tags": ["support"], "can_send_sms": true, "can_receive_sms": true } ], "pagination": { "total": 1, "limit": 10, "offset": 0 } } } ``` ### Einzelne Nummer per ID `GET /api/v1/numbers/{piv_num_id}` Vollständiger Nummernдатensatz: Status, Daten, Auto-Verlängerung, Tags, erlaubte SMS-Richtungen. **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Nummer nicht gefunden oder gehört nicht zum Konto. | **curl** ```bash curl https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "country_code": "SE", "status": "active", "created_at": "2026-05-01T10:00:00Z", "expires_at": "2026-05-31T10:00:00Z", "auto_renew": false, "custom_name": "Office line", "purchased_at": "2026-05-01T10:00:00Z", "next_renewal_date": "2026-05-31T10:00:00Z", "tags": ["support"], "can_send_sms": true, "can_receive_sms": true } } ``` ### Nummer kaufen `POST /api/v1/numbers/purchase` Kauft eine einzelne Nummer im gewählten Land für den angegebenen Zeitraum. Der Betrag wird vom Kontoguthaben abgezogen. Gibt `piv_num_id` zurück, das in allen weiteren Nummernoperationen verwendet wird. **Request body** | Field | Type | Description | | --- | --- | --- | | `country_code` * | string | ISO-Ländercode. | | `duration_months` * | integer | Mietdauer in Monaten (Minimum 1). | | `auto_renew` * | boolean | Auto-Verlängerung direkt nach dem Kauf aktivieren. | | `custom_name` | string | Optionaler, lesbarer Name für die Nummer. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `COUNTRY_NOT_AVAILABLE` | 400 | Land nicht verfügbar oder keine Preise vorhanden. | | `NO_NUMBERS_AVAILABLE` | 400 | Derzeit keine freien Nummern im angeforderten Land verfügbar. | | `INSUFFICIENT_BALANCE` | 402 | Nicht genügend Guthaben für den Kauf. | | `VALIDATION_ERROR` | 400 | Ungültige Felder im Anfrage-Body. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/purchase \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "country_code": "SE", "duration_months": 1, "auto_renew": false, "custom_name": "My Sweden Number" }' ``` **200 OK** ```json { "success": true, "cost": 5.00, "numbers": [ { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "country_code": "SE", "phone_number": "+46764794425", "created_at": "2026-05-01T10:00:00Z", "expires_at": "2026-05-31T10:00:00Z", "auto_renew": false, "custom_name": "My Sweden Number" } ] } ``` ### Nummer verlängern `POST /api/v1/numbers/{piv_num_id}/renew` Verlängert eine aktive Nummer für den angegebenen Zeitraum. Der Betrag wird beim Aufruf abgezogen. **Request body** | Field | Type | Description | | --- | --- | --- | | `duration_months` * | integer | Anzahl der Monate, um die verlängert werden soll. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Nummer nicht gefunden oder gehört nicht zum Konto. | | `COUNTRY_NOT_AVAILABLE` | 400 | Keine Preise für das Land der Nummer gefunden. | | `INSUFFICIENT_BALANCE` | 402 | Nicht genügend Guthaben für die Verlängerung. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/renew \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "duration_months": 1 }' ``` **200 OK** ```json { "success": true, "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "old_expires_at": "2026-05-31T10:00:00Z", "new_expires_at": "2026-06-30T10:00:00Z", "cost": 5.00 } } ``` ### Nummer aktualisieren `PATCH /api/v1/numbers/{piv_num_id}` Derzeit kann nur der benutzerdefinierte Name aktualisiert werden. **Request body** | Field | Type | Description | | --- | --- | --- | | `custom_name` * | string | Neuer Name für die Nummer. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Nummer nicht gefunden oder gehört nicht zum Konto. | | `VALIDATION_ERROR` | 400 | Ungültiger Wert im Anfrage-Body. | **curl** ```bash curl -X PATCH https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "custom_name": "Support line" }' ``` **200 OK** ```json { "success": true, "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "country_code": "SE", "status": "active", "custom_name": "Support line", "auto_renew": false, "expires_at": "2026-05-31T10:00:00Z", "tags": [] } } ``` ### Auto-Verlängerung verwalten `PATCH /api/v1/numbers/{piv_num_id}/auto-renewal` Schaltet die automatische Verlängerung der Nummer ein oder aus. Wenn aktiviert, wird die Verlängerung automatisch 24 Stunden vor Ablauf abgebucht. Bei fehlendem Guthaben läuft die Nummer ab; Sie können sie über `POST /numbers/restore` innerhalb von 7 Tagen zurückfordern. **Request body** | Field | Type | Description | | --- | --- | --- | | `auto_renew` * | boolean | Neuer Wert des Auto-Verlängerungs-Flags. | **curl** ```bash curl -X PATCH https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/auto-renewal \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "auto_renew": true }' ``` **200 OK** ```json { "success": true, "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "auto_renew": true } } ``` ### Abgelaufene Nummern wiederherstellen `POST /api/v1/numbers/restore` Stellt abgelaufene Nummern innerhalb eines 7-Tage-Fensters wieder her. Übergeben Sie ein Array von `piv_num_id` — Nummern kehren mit SMS-Verlauf und gespeicherten Einstellungen zurück. Die Wiederherstellung kostet mehr als der Kauf einer neuen Nummer (enthält einen Wiederherstellungs-Multiplikator) — genaue Zahlen erscheinen vor der Bestätigung im Dashboard. Der endgültige Status jeder Nummer kommt über den `number.restore_completed`-Webhook; Rückerstattungen für erfolglose Nummern werden automatisch gutgeschrieben. **Request body** | Field | Type | Description | | --- | --- | --- | | `piv_num_ids` * | string[] | Array der Nummern-IDs zur Wiederherstellung. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `NO_RESTORABLE_NUMBERS` | 404 | Keine der angegebenen Nummern kann wiederhergestellt werden (7-Tage-Fenster abgelaufen oder nicht Ihre). | | `INSUFFICIENT_BALANCE` | 402 | Nicht genügend Guthaben für die Wiederherstellung. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/restore \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "piv_num_ids": [ "vzPA1-kHKSg-EAL7e-Jqd3o", "abc12-defgh-ijklm-nopqr" ] }' ``` **200 OK** ```json { "success": true, "queued": 2, "skipped": 0, "total_charged": 9.00, "numbers": [ { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "status": "pending" } ] } ``` ### SMS-Verlauf für Nummer `GET /api/v1/numbers/{piv_num_id}/sms` Gibt ein- und ausgehende Nachrichten für die Nummer in umgekehrter chronologischer Reihenfolge zurück. **Query parameters** | Field | Type | Description | | --- | --- | --- | | `limit` | integer | Wie viele Nachrichten zurückgegeben werden sollen (Standard 50, max. 200). | | `offset` | integer | Paginierungs-Offset. | **curl** ```bash curl "https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/sms?limit=20" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "messages": [ { "id": "42", "from_number": "+46764794425", "to_number": "+14155551234", "message_body": "Hello from piv.day", "direction": "outbound", "status": "delivered", "received_at": "2026-05-22T11:30:00Z" }, { "id": "41", "from_number": "+14155551234", "to_number": "+46764794425", "message_body": "Hey, got your message!", "direction": "inbound", "status": "received", "received_at": "2026-05-22T11:35:00Z" } ], "pagination": { "total": 2, "limit": 20, "offset": 0 } } } ``` ### SMS senden `POST /api/v1/numbers/{piv_num_id}/sms/send` Verfügbar für Länder, in denen ausgehende Nachrichten erlaubt sind (z. B. CA, GB, SE). Die Nachrichtenkosten werden beim Senden abgebucht. **Request body** | Field | Type | Description | | --- | --- | --- | | `to_number` * | string | Empfängernummer im internationalen Format (E.164). | | `message_body` * | string | Nachrichtentext. GSM-7 und UCS-2 werden unterstützt. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Nummer nicht gefunden oder gehört nicht zum Konto. | | `NUMBER_EXPIRED` | 403 | Nummer ist bereits abgelaufen. | | `NUMBER_NOT_ACTIVE` | 400 | Nummer befindet sich in einem Zustand, der das Senden nicht erlaubt. | | `INSUFFICIENT_BALANCE` | 402 | Nicht genügend Guthaben zum Senden. | | `INVALID_MESSAGE_FORMAT` | 400 | Nachrichteninhalt überschreitet die zulässige Länge oder enthält verbotene Zeichen. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/sms/send \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "to_number": "+14155551234", "message_body": "Hello from piv.day" }' ``` **200 OK** ```json { "success": true, "data": { "message_id": "42", "from_number": "+46764794425", "to_number": "+14155551234", "message_body": "Hello from piv.day", "status": "queued", "created_at": "2026-05-22T11:30:00Z" } } ``` ### Google QR-Verifizierung starten `POST /api/v1/numbers/{piv_num_id}/verify` Startet eine Google QR-Verifizierung mit der angegebenen URL. Das Ergebnis — Erfolg oder Fehler — kommt über den Webhook verify.completed oder verify.failed. Der Betrag wird beim Einreihen der Aufgabe abgebucht. **Request body** | Field | Type | Description | | --- | --- | --- | | `gv_url` * | string | Vollständige Google-Verifizierungs-URL (von der Google-Seite kopiert). | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `NUMBER_NOT_FOUND` | 404 | Nummer nicht gefunden oder gehört Ihnen nicht. | | `NUMBER_NOT_ACTIVE` | 400 | Nummer ist nicht aktiv. | | `SMS_DISABLED` | 400 | SMS-Versand ist für diese Nummer deaktiviert. | | `INSUFFICIENT_BALANCE` | 402 | Nicht genügend Guthaben für die Verifizierung. | | `PROXY_DEAD` | 502 | Proxy nicht verfügbar — Guthaben zurückerstattet. | | `QUEUE_FULL` | 503 | Warteschlange voll, später nochmals versuchen — Guthaben zurückerstattet. | | `SERVER_UNAVAILABLE` | 503 | Automatisierungsserver nicht verfügbar — Guthaben zurückerstattet. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/numbers/vzPA1-kHKSg-EAL7e-Jqd3o/verify \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "gv_url": "https://gv.google.com/..." }' ``` **202 Accepted** ```json { "success": true, "message": "Verification initiated" } ``` ## Proxy Residential-IPv6 in Dutzenden Ländern. Massenkauf, Verlängerung, Restore mit gleichem Login und Passwort, Export im gewünschten Format. ### Serverliste `GET /api/v1/proxy/servers` Verfügbare Proxy-Server mit Preisen. **curl** ```bash curl https://app.piv.day/api/v1/proxy/servers \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "servers": [ { "id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "name": "EU-DE-01", "country": "DE", "socks5_port": 1080, "http_port": 3128, "price_per_proxy": 0.50 }, { "id": "b2c3d4e5-f6a7-8901-bcde-f12345678901", "name": "EU-NL-01", "country": "NL", "socks5_port": 1080, "http_port": 3128, "price_per_proxy": 0.45 } ] } } ``` ### Bestellliste `GET /api/v1/proxy/orders` Liste deiner Proxy-Bestellungen mit Filterung nach Status oder Suche. **Query parameters** | Field | Type | Description | | --- | --- | --- | | `limit` | integer | Seitengröße. Standard 100, Maximum 500. | | `offset` | integer | Paginierungsversatz. | | `status` | string | Statusfilter: `active`, `expired`. | | `search` | string | Bestellungen durchsuchen. | **curl** ```bash curl "https://app.piv.day/api/v1/proxy/orders?status=active&limit=20" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "orders": [ { "id": "ord-uuid-...", "country": "DE", "quantity": 10, "price_per_proxy": 0.50, "price_total": 5.00, "status": "active", "purchased_at": "2026-01-01T00:00:00Z", "expires_at": "2026-02-01T00:00:00Z" } ], "pagination": { "total": 1, "limit": 20, "offset": 0 } } } ``` ### Eine Bestellung abrufen `GET /api/v1/proxy/orders/{id}` Details einer bestimmten Bestellung abrufen, einschließlich der Liste der Proxy-Zugangsdaten. **curl** ```bash curl https://app.piv.day/api/v1/proxy/orders/ord-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "order": { "id": "ord-uuid-...", "country": "DE", "quantity": 10, "price_per_proxy": 0.50, "price_total": 5.00, "status": "active", "purchased_at": "2026-01-01T00:00:00Z", "expires_at": "2026-02-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "items": [ { "login": "user1", "password": "pass1", "host": "185.1.2.3", "socks5_port": 1080, "http_port": 3128, "ipv6": "2a00:1:2:3::1" } ] } } } ``` ### Proxys kaufen `POST /api/v1/proxy/purchase` Proxys auf dem gewählten Server kaufen. Eine Anfrage erstellt eine Bestellung mit N Proxys (bis zu 500). Es gibt keine Bulk-Bestellungen — rufe die Methode erneut auf, wenn du mehr benötigst. **Request body** | Field | Type | Description | | --- | --- | --- | | `server_id` * | string | Server-ID aus `GET /proxy/servers`. | | `quantity` * | integer | Anzahl der zu kaufenden Proxys (1–500). | | `months` * | integer | Mietdauer in Monaten (1–12). | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `INSUFFICIENT_BALANCE` | 402 | Nicht genug Guthaben. | | `NOT_FOUND` | 404 | Proxy-Server nicht gefunden oder inaktiv. | | `VALIDATION_ERROR` | 400 | Ungültiger Anfrage-Body. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/proxy/purchase \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "server_id": "a1b2c3d4-e5f6-7890-abcd-ef1234567890", "quantity": 5, "months": 1 }' ``` **200 OK** ```json { "success": true, "data": { "order": { "id": "ord-uuid-...", "country": "DE", "quantity": 5, "price_total": 2.50, "status": "active", "expires_at": "2026-02-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "items": [ { "login": "user1", "password": "pass1", "host": "185.1.2.3", "socks5_port": 1080, "http_port": 3128, "ipv6": "2a00:1:2:3::1" }, { "login": "user2", "password": "pass2", "host": "185.1.2.3", "socks5_port": 1080, "http_port": 3128, "ipv6": "2a00:1:2:3::2" } ] } } } ``` ### Bestellung verlängern `POST /api/v1/proxy/orders/{id}/renew` Eine aktive Proxy-Bestellung um eine bestimmte Anzahl von Monaten verlängern. **Request body** | Field | Type | Description | | --- | --- | --- | | `months` * | integer | Anzahl der hinzuzufügenden Monate. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../renew \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "months": 1 }' ``` **200 OK** ```json { "success": true, "data": { "order_id": "ord-uuid-...", "cost": 5.00, "new_expires_at": "2026-03-01T00:00:00Z" } } ``` ### Abgelaufene Bestellung wiederherstellen `POST /api/v1/proxy/orders/{id}/restore` Eine abgelaufene Proxy-Bestellung ohne Neukauf reaktivieren. Login, Passwort, IPv6-Adressen, Land und Bindungen bleiben dieselben. Die Laufzeit wird um 1 Monat verlängert. Eine Neukonfiguration des Antidetect-Browsers ist nicht nötig. **curl** ```bash curl -X POST https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../restore \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "order_id": "ord-uuid-...", "quantity": 10, "total_cost": 5.00, "expires_at": "2026-03-01T00:00:00Z" } } ``` ### Proxys exportieren `GET /api/v1/proxy/orders/{id}/export` Die Proxy-Zugangsdaten der Bestellung als Textliste exportieren (login:password@host:port). **Query parameters** | Field | Type | Description | | --- | --- | --- | | `format` | string | Exportformat: `socks5`, `http` oder `both` (Standard `socks5`). | **curl** ```bash curl "https://app.piv.day/api/v1/proxy/orders/ord-uuid-.../export?format=socks5" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "content": "user1:pass1@1.2.3.4:1080\nuser2:pass2@1.2.3.4:1080", "filename": "piv-day-proxy-ord-uuid--socks5.txt", "format": "socks5", "count": 2 } } ``` ## Domains Suche und Registrierung ohne KYC, automatisches Cloudflare und SSL, Verwaltung von DNS-Einträgen und Nameservern über die API. ### Verfügbarkeitsprüfung `GET /api/v1/domains/search` Prüfen, ob eine Domain verfügbar ist und wie viel die Registrierung kostet. **Query parameters** | Field | Type | Description | | --- | --- | --- | | `q` * | string | Zu suchender Domainname, z. B. `mysite.com`. | **curl** ```bash curl "https://app.piv.day/api/v1/domains/search?q=mysite.com" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "domain": "mysite.com", "available": true, "create_price": 12.50, "renew_price": 12.50, "currency": "USD" } } ``` ### Domains auflisten `GET /api/v1/domains` Liste Ihrer registrierten Domains mit Filtermöglichkeit. **Query parameters** | Field | Type | Description | | --- | --- | --- | | `limit` | integer | Seitengröße. Standard 100, Maximum 500. | | `offset` | integer | Offset für die Paginierung. | | `status` | string | Domain-Status: `active`, `pending`, `expired`. | | `cloudflare` | string | Nach Cloudflare-Status filtern: `true` oder `false`. | | `auto_renew` | string | Nach automatischer Verlängerung filtern: `true` oder `false`. | | `search` | string | Suche nach Domainname. | **curl** ```bash curl "https://app.piv.day/api/v1/domains?status=active&limit=20" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "domains": [ { "id": "dom-uuid-...", "domain_name": "mysite.com", "status": "active", "registered_at": "2026-01-01T00:00:00Z", "expires_at": "2027-01-01T00:00:00Z", "auto_renew": true, "cloudflare_enabled": true, "cloudflare_status": "active", "ssl_type": "lets_encrypt", "ssl_status": "active", "ssl_mode": "full", "ssl_expires_at": "2026-04-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T00:00:00Z" } ], "pagination": { "total": 1, "limit": 20, "offset": 0 } } } ``` ### Domain registrieren `POST /api/v1/domains` Eine neue Domain registrieren. Die Anfrage ist asynchron — gibt `queue_id` zur Nachverfolgung zurück. Cloudflare EIN: `nameservers` nicht übergeben; optional können `dns_records` und `ssl_mode` übergeben werden. Cloudflare AUS: `dns_records` und `ssl_mode` nicht übergeben; `nameservers` ist erforderlich (mindestens 2). Cloudflare-Nameserver geben wir nie preis. **Request body** | Field | Type | Description | | --- | --- | --- | | `domain` * | string | Zu registrierender Domainname, z. B. `mysite.com`. | | `period` * | integer | Registrierungsdauer in Jahren (1–10). | | `cloudflare` * | boolean | Die Domain automatisch mit Cloudflare verbinden. | | `auto_renew` * | boolean | Automatische Verlängerung aktivieren. | | `ssl_mode` | string | `flexible` \| `full` \| `strict`. Nur bei `cloudflare: true`. | | `nameservers` | string[] | Erforderlich bei `cloudflare: false` (≥2 NS). Verboten bei `cloudflare: true`. | | `dns_records` | object[] | Initiale DNS-Einträge. Nur bei `cloudflare: true`. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `DOMAIN_NOT_AVAILABLE` | 400 | Domain ist nicht für die Registrierung verfügbar. | | `INSUFFICIENT_BALANCE` | 402 | Nicht genügend Guthaben. | | `VALIDATION_ERROR` | 400 | Ungültiger Anfrage-Body. | **Cloudflare EIN** ```bash curl -X POST https://app.piv.day/api/v1/domains \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domain": "mysite.com", "period": 1, "cloudflare": true, "auto_renew": true, "ssl_mode": "full", "dns_records": [ { "type": "A", "name": "@", "content": "1.2.3.4", "proxied": true } ] }' ``` **Cloudflare AUS — eigene NS** ```bash curl -X POST https://app.piv.day/api/v1/domains \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "domain": "mysite.com", "period": 1, "cloudflare": false, "auto_renew": false, "nameservers": ["ns1.myhost.com", "ns2.myhost.com"] }' ``` **202 Accepted** ```json { "success": true, "data": { "queue_id": "que-uuid-...", "domain": { "id": "dom-uuid-...", "domain_name": "mysite.com", "status": "purchasing", "period": 1, "cloudflare_enabled": true, "auto_renew": true, "ssl_mode": "full", "created_at": "2026-01-01T00:00:00Z" } } } ``` ### Registrierungswarteschlangen-Status `GET /api/v1/domains/queue/{id}` Den Status eines Registrierungs- oder Verlängerungs-Warteschlangeneintrags prüfen. Bei Status `completed` enthält die Antwort bereits die vollständige Domain-Karte — ein separater Aufruf an `/domains/{id}` ist nicht nötig. **curl** ```bash curl https://app.piv.day/api/v1/domains/queue/que-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` **pending / processing** ```json { "success": true, "data": { "queue_id": "que-uuid-...", "domain": "mysite.com", "status": "pending" } } ``` **completed — vollständige Karte** ```json { "success": true, "data": { "queue_id": "que-uuid-...", "status": "completed", "domain": { "id": "dom-uuid-...", "domain_name": "mysite.com", "status": "active", "registered_at": "2026-01-01T12:00:00Z", "expires_at": "2027-01-01T12:00:00Z", "auto_renew": true, "cloudflare_enabled": true, "cloudflare_status": "active", "ssl_type": "lets_encrypt", "ssl_status": "active", "ssl_mode": "full", "ssl_expires_at": "2026-04-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T12:00:00Z", "dns_records": [ { "name": "@", "type": "A", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true } ] } } } ``` ### Eine Domain abrufen `GET /api/v1/domains/{id}` Vollständige Informationen zu einer registrierten Domain abrufen. Das Feld `nameservers` ist nur vorhanden, wenn `cloudflare_enabled: false`. **curl** ```bash curl https://app.piv.day/api/v1/domains/dom-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "domain": { "id": "dom-uuid-...", "domain_name": "mysite.com", "status": "active", "registered_at": "2026-01-01T12:00:00Z", "expires_at": "2027-01-01T12:00:00Z", "auto_renew": true, "cloudflare_enabled": true, "cloudflare_status": "active", "ssl_type": "lets_encrypt", "ssl_status": "active", "ssl_mode": "full", "ssl_expires_at": "2026-04-01T00:00:00Z", "created_at": "2026-01-01T00:00:00Z", "updated_at": "2026-01-01T12:00:00Z", "dns_records": [ { "name": "@", "type": "A", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true }, { "name": "www", "type": "CNAME", "content": "mysite.com", "ttl": 1, "priority": null, "proxied": true } ] } } } ``` ### Domain verlängern `POST /api/v1/domains/{id}/renew` Die Domain-Registrierung verlängern. Gibt `queue_id` zur Nachverfolgung zurück. **Request body** | Field | Type | Description | | --- | --- | --- | | `period` * | integer | Anzahl der Jahre, um die verlängert wird. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../renew \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "period": 1 }' ``` **202 Accepted** ```json { "success": true, "data": { "queue_id": "que-uuid-...", "domain_id": "dom-uuid-...", "expires_at": "2027-01-01T12:00:00Z" } } ``` ### Auto-Verlängerung umschalten `POST /api/v1/domains/{id}/auto-renew` Die automatische Verlängerung der Domain ein- oder ausschalten. **Request body** | Field | Type | Description | | --- | --- | --- | | `auto_renew` * | boolean | Neuer Wert des Flags. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../auto-renew \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "auto_renew": true }' ``` **200 OK** ```json { "success": true, "data": { "id": "dom-uuid-...", "auto_renew": true } } ``` ### DNS-Einträge der Domain `GET /api/v1/domains/{id}/dns` DNS-Einträge der Domain auflisten (über Cloudflare). **curl** ```bash curl https://app.piv.day/api/v1/domains/dom-uuid-.../dns \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "records": [ { "id": "rec-uuid-...", "type": "A", "name": "@", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true } ] } } ``` ### DNS-Eintrag hinzufügen `POST /api/v1/domains/{id}/dns` Einen neuen DNS-Eintrag erstellen. **Request body** | Field | Type | Description | | --- | --- | --- | | `type` * | string | Eintragstyp: `A`, `AAAA`, `CNAME`, `MX`, `TXT` usw. | | `name` * | string | Name des Eintrags, z. B. `@` oder `subdomain`. | | `content` * | string | Wert des Eintrags. | | `ttl` | integer | TTL in Sekunden (`1` = automatisch). | | `proxied` | boolean | Über Cloudflare weiterleiten. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../dns \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "type": "A", "name": "@", "content": "1.2.3.4", "ttl": 1, "proxied": true }' ``` **201 Created** ```json { "success": true, "data": { "record": { "id": "rec-uuid-...", "type": "A", "name": "@", "content": "1.2.3.4", "ttl": 1, "priority": null, "proxied": true } } } ``` ### DNS-Eintrag aktualisieren `PUT /api/v1/domains/{id}/dns/{recordId}` Einen vorhandenen DNS-Eintrag per ID aktualisieren. Nur die übergebenen Felder werden überschrieben. **curl** ```bash curl -X PUT https://app.piv.day/api/v1/domains/dom-uuid-.../dns/rec-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "content": "5.6.7.8" }' ``` ### DNS-Eintrag löschen `DELETE /api/v1/domains/{id}/dns/{recordId}` Einen DNS-Eintrag per ID löschen. **curl** ```bash curl -X DELETE https://app.piv.day/api/v1/domains/dom-uuid-.../dns/rec-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` ### Cloudflare aktivieren `POST /api/v1/domains/{id}/cloudflare` Cloudflare für die Domain aktivieren. Wir geben keine Cloudflare-Nameserver zurück — die Delegierung wird auf unserer Seite eingerichtet. Das Deaktivieren von Cloudflare über diesen Endpunkt wird nicht unterstützt. **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../cloudflare \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "enabled": true }' ``` **200 OK** ```json { "success": true, "data": { "domain_id": "dom-uuid-...", "ssl_mode": "flexible" } } ``` ### Nameserver setzen `POST /api/v1/domains/{id}/ns-servers` Benutzerdefinierte Nameserver für die Domain festlegen. **curl** ```bash curl -X POST https://app.piv.day/api/v1/domains/dom-uuid-.../ns-servers \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "nameservers": ["ns1.example.com", "ns2.example.com"] }' ``` **200 OK** ```json { "success": true, "data": { "nameservers": [ { "nameserver": "ns1.example.com", "order_index": 1 }, { "nameserver": "ns2.example.com", "order_index": 2 } ] } } ``` ## Whites White-Page-Generierung nach Nische und Tier. Jede Website ist einzigartig. Domain und Kontakte tauschen — ohne erneute Generierung. ### Tiers auflisten `GET /api/v1/whites/tiers` Verfügbare Generierungs-Tiers mit Preisen. `price` ist der Preis pro Generierung, bereits auf Ihr Konto angepasst (Abonnement berücksichtigt), eine einzige Zahl. `quality: "premium"` kostet mehr (wird beim Erstellen berechnet). Blog nur bei `v2_tier3`: die ersten 3 Artikel sind enthalten, jeder weitere (bis 20) wird zu `extra_article_price` berechnet. **curl** ```bash curl https://app.piv.day/api/v1/whites/tiers \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "tiers": [ { "tier_key": "v2_tier1", "name": "Landing", "generator_version": "v2", "min_articles": 0, "max_articles": 0, "price": 3.00, "extra_article_price": null }, { "tier_key": "v2_tier2", "name": "Multi-page", "generator_version": "v2", "min_articles": 0, "max_articles": 0, "price": 6.00, "extra_article_price": null }, { "tier_key": "v2_tier3", "name": "Full + Blog", "generator_version": "v2", "min_articles": 3, "max_articles": 20, "price": 10.00, "extra_article_price": 1.50 } ] } } ``` ### Whites auflisten `GET /api/v1/whites` Liste Ihrer Generierungsaufträge mit Filtermöglichkeit. **Query parameters** | Field | Type | Description | | --- | --- | --- | | `limit` | integer | Seitengröße. Standard 100, maximal 500. | | `offset` | integer | Paginierungs-Offset. | | `status` | string | `queued` \| `processing` \| `done` \| `failed`. | | `tier_key` | string | `v2_tier1` \| `v2_tier2` \| `v2_tier3`. | **curl** ```bash curl "https://app.piv.day/api/v1/whites?status=done&limit=20" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "whites": [ { "id": "job-uuid-...", "name": "My White", "status": 10, "tier_key": "v2_tier3", "quality": "standard", "niche": "IT Consulting", "country": "DE", "language": "de", "domain": "mysite.com", "result_url": null, "created_at": "2026-01-01T00:00:00Z" } ], "pagination": { "total": 1, "limit": 20, "offset": 0 } } } ``` ### Generierung starten `POST /api/v1/whites` Einen White-Page-Generierungsauftrag in die Warteschlange stellen. Die Zahlung erfolgt sofort. Der finale Status kommt über den Webhook `white.completed` / `white.failed` oder kann über `GET /whites/{id}` abgefragt werden. **Request body** | Field | Type | Description | | --- | --- | --- | | `name` * | string | Auftragsname (2–20 Zeichen). | | `tier_key` * | string | `v2_tier1` \| `v2_tier2` \| `v2_tier3`. | | `niche` * | string | Website-Nische (bis zu 25 Zeichen). | | `country` * | string | Ländercode (ISO 3166-1 alpha-2). | | `language` * | string | Primäre Website-Sprache (ISO 639-1). | | `quality` | string | `standard` \| `premium` (Standard: `standard`). | | `languages` | string[] | Sprachenliste. Die erste ist im Preis enthalten; jede weitere kostet extra. | | `domain` | string | Vollständige Domain (z. B. `example.com`). Keine Autovervollständigung. | | `email` | string | Vollständige E-Mail-Adresse (z. B. `info@example.com`). Keine Autovervollständigung. | | `phone` | string | Kontakttelefon. | | `address` | string | Unternehmensadresse. | | `legal_name` | string | Firmenname (rechtlich). | | `style_hint` | string | Designstil (Random, Minimalistisch, Korporativ usw.). | | `keywords` | string[] | SEO-Keywords. | | `banned_words` | string[] | Im Inhalt verbotene Wörter. | | `blog_count` | integer | Anzahl der Blog-Artikel 3–20. Nur für `v2_tier3`. Artikel über 3 kosten extra. | | `contacts_mode` | string | `same` \| `template`. | | `contacts_template` | string | Kontaktseiten-Template (wenn `contacts_mode=template`). | | `facebook` | string | Vollständige Facebook-Seiten-URL. | | `instagram` | string | Vollständige Instagram-Profil-URL. | | `linkedin` | string | Vollständige LinkedIn-Profil-URL. | | `youtube` | string | Vollständige YouTube-Kanal-URL. | | `tiktok` | string | Vollständige TikTok-Profil-URL. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `INSUFFICIENT_BALANCE` | 402 | Nicht genügend Guthaben. | | `INVALID_TIER` | 400 | Kein Tier mit diesem Schlüssel gefunden. | | `VALIDATION_ERROR` | 400 | Ungültiger Anfrage-Body. | **curl** ```bash curl -X POST https://app.piv.day/api/v1/whites \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Tech Blog DE", "tier_key": "v2_tier3", "niche": "IT Consulting", "country": "DE", "language": "de", "quality": "premium", "languages": ["de", "en"], "domain": "techblog-de.com", "email": "info@techblog-de.com", "phone": "+49 30 123456", "address": "Berliner Str. 1, 10115 Berlin", "legal_name": "TechBlog GmbH", "style_hint": "Корпоративный", "keywords": ["IT", "consulting", "cloud"], "banned_words": ["cheap", "free"], "blog_count": 8, "contacts_mode": "same", "facebook": "https://facebook.com/techblogde", "instagram": "https://instagram.com/techblogde", "linkedin": "https://linkedin.com/company/techblogde" }' ``` **200 OK** ```json { "success": true, "data": { "status": "queued", "white": { "id": "job-uuid-...", "name": "Tech Blog DE", "status": 0, "tier_key": "v2_tier3", "quality": "premium", "niche": "IT Consulting", "country": "DE", "language": "de", "domain": "techblog-de.com", "result_url": null, "created_at": "2026-01-01T00:00:00Z" } } } ``` ### Einen White abrufen `GET /api/v1/whites/{id}` Den aktuellen Status eines Generierungsauftrags abrufen. **curl** ```bash curl https://app.piv.day/api/v1/whites/job-uuid-... \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "white": { "id": "job-uuid-...", "name": "Tech Blog DE", "status": 10, "tier_key": "v2_tier3", "quality": "premium", "niche": "IT Consulting", "country": "DE", "language": "de", "domain": "techblog-de.com", "result_url": null, "created_at": "2026-01-01T00:00:00Z" } } } ``` ### Archiv herunterladen `GET /api/v1/whites/{id}/download` Einen kurzlebigen signierten Link zum fertigen White-Page-Archiv abrufen. Der Link ist ~5 Minuten gültig (siehe `expires_at`). Falls abgelaufen — einfach `/download` erneut aufrufen, wir stellen einen neuen aus. Wenn die White Page noch nicht generiert wurde, wird `409 NOT_READY` zurückgegeben. **Query parameters** | Field | Type | Description | | --- | --- | --- | | `format` | string | Archivformat. Standard: `php`. | **Errors** | Code | HTTP | When it fires | | --- | --- | --- | | `NOT_READY` | 409 | Die White Page wird noch generiert — nach `white.completed` erneut versuchen. | **curl** ```bash curl "https://app.piv.day/api/v1/whites/job-uuid-.../download?format=php" \ -H "Authorization: Bearer YOUR_API_KEY" ``` **200 OK** ```json { "success": true, "data": { "url": "https://strg.piv.day/download//?format=php&token=&filename=.zip", "filename": "example.com_2026-05-28_DE_en.zip", "format": "php", "expires_at": "2026-05-28T14:46:00Z" } } ``` ### Domain und Kontakte tauschen `POST /api/v1/whites/{id}/config` Die Unternehmenskontaktdaten der White Page aktualisieren, ohne sie neu zu generieren. **curl** ```bash curl -X POST https://app.piv.day/api/v1/whites/job-uuid-.../config \ -H "Authorization: Bearer YOUR_API_KEY" \ -H "Content-Type: application/json" \ -d '{ "company": "My Brand", "domain": "newdomain.com", "email": "info@newdomain.com", "phone": "+49 30 123456", "address": "Berliner Str. 1, Berlin", "legal": "My Brand GmbH" }' ``` ## Webhooks Wir senden einen einfachen POST mit JSON-Body an deine URL. Das Format ist für alle Events gleich: `event_type`, `timestamp` und ein `data`-Block. Dein Server muss innerhalb von 5 Sekunden mit einem 2xx antworten. ``` POST Content-Type: application/json User-Agent: piv.day-webhook/1.0 { "event_type": "", "timestamp": "2026-05-22T12:34:56Z", "data": { ... } } ``` **Retries.** Bei nicht-2xx oder Timeout — bis zu 3 Wiederholungen mit 1s / 2s / 4s Backoff. Der vollständige Lieferverlauf befindet sich auf der API-Schlüssel-Seite im Dashboard. Schlagen alle drei fehl, wird das Event als failed markiert und kann manuell wiederholt werden. **Security.** Verwende einen HTTPS-Endpunkt. Jede Anfrage kommt mit dem Header `User-Agent: piv.day-webhook/1.0`. Die Webhook-URL wird im API-Schlüssel-Profil konfiguriert. ### All events | Event | When it fires | | --- | --- | | `sms.received` | Ein vertrauenswürdiger Absender hat soeben eine Nachricht an eine deiner Nummern gesendet. | | `sms.status_updated` | Eine ausgehende SMS hat den Status geändert — zugestellt, fehlgeschlagen usw. | | `number.restore_completed` | Ein Batch-Restore ist abgeschlossen — die finale Zusammenfassung landet hier. | | `verify.completed` | Die Google-Kontoüberprüfung wurde erfolgreich abgeschlossen. | | `verify.failed` | Etwas ist schief gelaufen — Google hat es nicht akzeptiert. | | `proxy.expires_soon` | Noch etwa drei Tage bis zum Ende der Proxy-Bestellung. | | `domain.registered` | Die Registrierungsbestellung wurde erfolgreich abgeschlossen — die Domain ist aktiv. | | `domain.failed` | Die Bestellung wurde nicht abgeschlossen — häufige Ursache: Name wurde gerade registriert. | | `domain.expires_soon` | Noch etwa eine Woche bis zum Ablauf der Domain. | | `white.completed` | Der White-Generierungsauftrag wurde erfolgreich abgeschlossen. | | `white.failed` | Der Auftrag ist fehlgeschlagen — das Guthaben wird dem Konto gutgeschrieben. | ### Eingehende SMS auf deine Nummer **`sms.received`** Meistens sind es Bestätigungscodes von Werbenetzwerken. Der Payload enthält sowohl den Rohtext als auch einen automatisch erkannten Code (wenn vorhanden), sodass du ihn direkt in deinen Workflow übergeben kannst ohne Parsing. Nachrichten von bekannten Spam-Absendern werden nicht weitergeleitet. ```json { "event_type": "sms.received", "timestamp": "2026-05-22T12:34:56Z", "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "text": "Your verification code is 123456", "code": "123456", "country": "SE", "received_at": "2026-05-22T12:34:56Z" } } ``` ### Status der ausgehenden SMS geändert **`sms.status_updated`** Nützlich, wenn du Bestätigungen von deiner eigenen Nummer sendest und wissen möchtest, ob sie wirklich angekommen sind. Wenn der Status failed ist, enthält der Payload den Fehlercode und die Fehlermeldung des Netzbetreibers. ```json { "event_type": "sms.status_updated", "timestamp": "2026-05-22T12:34:56Z", "data": { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "message_id": "42", "old_status": "sent", "new_status": "delivered", "error_code": null, "error_message": null } } ``` ### Nummernwiederherstellung abgeschlossen **`number.restore_completed`** Enthält zwei Listen — welche Nummern zurückgekehrt sind und welche nicht. Der erstattete Betrag für fehlgeschlagene ist ebenfalls im Payload. Praktisch für Skripte, die intelligent wiederholen. ```json { "event_type": "number.restore_completed", "timestamp": "2026-05-22T12:34:56Z", "data": { "restored": [ { "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "phone_number": "+46764794425", "country": "SE" } ], "failed": [ { "piv_num_id": "abc12-defgh-ijklm-nopqr", "phone_number": "+46123456789", "country": "SE", "refunded": 7.50 } ], "total_restored": 1, "total_failed": 1, "total_refunded": 7.50 } } ``` ### Google QR-Verifizierung erfolgreich **`verify.completed`** Wenn während des Vorgangs eine SMS mit Code angekommen ist, ist sie bereits hier — kein extra Abruf nötig. captured_phone und captured_message enthalten das, was Google gesendet hat. ```json { "event_type": "verify.completed", "timestamp": "2026-05-22T12:34:56Z", "data": { "task_id": 12, "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "status": "sms_sent", "captured_phone": "+14155551234", "captured_message": "Your Google verification code is 123456", "sms_message_id": 42, "sms_status": "queued" } } ``` ### Google QR-Verifizierung fehlgeschlagen **`verify.failed`** error_code sagt dir genau was — Timeout, Ablehnung, ungültige URL. Fehlgeschlagene Verifizierungen werden automatisch dem Guthaben gutgeschrieben. ```json { "event_type": "verify.failed", "timestamp": "2026-05-22T12:34:56Z", "data": { "task_id": 12, "piv_num_id": "vzPA1-kHKSg-EAL7e-Jqd3o", "status": "failed", "error_code": "VERIFY_TIMEOUT", "error_message": "Verification timed out" } } ``` ### Proxy läuft bald ab **`proxy.expires_soon`** Gedacht für Nutzer ohne automatische Verlängerung: du siehst es rechtzeitig und entscheidest — verlängern oder die Kampagne beenden. Verknüpfe es mit POST /proxy/orders/{id}/renew für vollautomatische Verlängerung. ```json { "event_type": "proxy.expires_soon", "timestamp": "2026-05-22T12:34:56Z", "data": { "order_id": "ord-uuid-...", "country": "DE", "quantity": 10, "expires_at": "2026-05-25T00:00:00Z" } } ``` ### Domain registriert **`domain.registered`** Wenn du bei der Bestellung Cloudflare und SSL angefordert hast, sind beide bereits aktiv — cloudflare_enabled zeigt den Status. Du kannst sofort DNS-Einträge hinzufügen oder die Website deployen. ```json { "event_type": "domain.registered", "timestamp": "2026-05-22T12:34:56Z", "data": { "domain_id": "dom-uuid-...", "domain_name": "mysite.com", "registered_at": "2026-05-22T12:34:56Z", "expires_at": "2027-05-22T12:34:56Z", "cloudflare_enabled": true } } ``` ### Domain-Registrierung fehlgeschlagen **`domain.failed`** Das error-Feld enthält eine menschenlesbare Erklärung. Der Betrag wird dem Guthaben gutgeschrieben. Wähle einen anderen Namen und versuche es erneut. ```json { "event_type": "domain.failed", "timestamp": "2026-05-22T12:34:56Z", "data": { "domain_id": "dom-uuid-...", "domain_name": "mysite.com", "error": "Domain is no longer available" } } ``` ### Domain läuft bald ab **`domain.expires_soon`** Nützlich, wenn die automatische Verlängerung ausgeschaltet ist: du hast Zeit, manuell zu verlängern, bevor die Domain in die Redemption-Phase geht. Das auto_renew-Flag sagt dir, ob ein Eingriff nötig ist. ```json { "event_type": "domain.expires_soon", "timestamp": "2026-05-22T12:34:56Z", "data": { "domain_id": "dom-uuid-...", "domain_name": "mysite.com", "expires_at": "2026-05-29T00:00:00Z", "auto_renew": false } } ``` ### White generiert **`white.completed`** Das Archiv ist über GET /whites/{id}/download verfügbar. Wenn für den White eine Domain gesetzt war, sind Sitemap und Kontakte bereits darauf eingestellt — bereit zum Deployen. ```json { "event_type": "white.completed", "timestamp": "2026-05-22T12:34:56Z", "data": { "job_id": "job-uuid-...", "name": "My White", "tier_key": "t1", "country": "DE" } } ``` ### White-Generierung fehlgeschlagen **`white.failed`** Das error-Feld erklärt den Grund. Starte direkt einen neuen Auftrag über POST /whites — kein Geldverlust. ```json { "event_type": "white.failed", "timestamp": "2026-05-22T12:34:56Z", "data": { "job_id": "job-uuid-...", "name": "My White", "error": "Generation failed" } } ``` ## Error codes Jede Fehlerantwort folgt demselben Schema: HTTP-Status + Feld `error.code` + lesbares `error.message`. ```json { "success": false, "error": { "code": "INSUFFICIENT_BALANCE", "message": "Not enough balance: required $5.00, available $1.20" } } ``` | Code | HTTP | When it fires | | --- | --- | --- | | `UNAUTHORIZED` | 401 | Schlüssel fehlt, ist abgelaufen oder wurde widerrufen. | | `INSUFFICIENT_PERMISSIONS` | 403 | Der Schlüssel besitzt nicht den erforderlichen Scope für diese Aktion. | | `PERMISSION_DENIED` | 403 | Der Zugriff auf Kontoebene erlaubt diese Aktion nicht (z. B. Funktion deaktiviert). | | `VALIDATION_ERROR` | 400 | Ungültiger Anfragekörper. Die Meldung erklärt, welches Feld betroffen ist und warum. | | `NUMBER_NOT_FOUND` | 404 | Die Nummer existiert nicht oder gehört nicht zum Konto. | | `NUMBER_EXPIRED` | 403 | Die Nummer ist abgelaufen — nutzen Sie Restore (innerhalb von 7 Tagen) oder kaufen Sie eine neue. | | `NUMBER_NOT_ACTIVE` | 400 | Die Nummer befindet sich in einem Zustand, der diese Operation nicht erlaubt. | | `INSUFFICIENT_BALANCE` | 402 | Nicht genügend Guthaben für diese Operation. | | `INVALID_MESSAGE_FORMAT` | 400 | Der SMS-Text ist zu lang oder enthält nicht erlaubte Zeichen. | | `COUNTRY_NOT_AVAILABLE` | 400 | Das Land ist für Kauf oder Verlängerung nicht verfügbar. | | `NO_NUMBERS_AVAILABLE` | 400 | Im gewählten Land sind derzeit keine freien Nummern verfügbar. | | `NO_RESTORABLE_NUMBERS` | 404 | Keiner der angegebenen Nummern kann noch wiederhergestellt werden. | | `RATE_LIMITED` | 429 | Rate limit überschritten. Warten Sie die im Header `Retry-After` angegebene Zeit. | | `INTERNAL_ERROR` | 500 | Bei uns ist ein Fehler aufgetreten. Falls er anhält — wenden Sie sich an den Support. |