Kierunek inbound: Twój system (Make, Zapier, CRM, własny backend) wysyła POST do Webivio i tworzy rejestrację na wybrany termin — tak jak zapis z formularza (powiadomienia, CRM, oraz ewentualny outbound webhook webinar.registration.created).
To nie jest to samo co webhooki outbound (Webivio → Twój URL).
Dla serii webinarów zobacz sekcję Rejestracja na serię webinarów poniżej.
Dla WooCommerce (jeden URL, zapis na najbliższy termin bez selectedDate) zobacz Webhook WooCommerce.
Gdzie wziąć URL
- Kreator webinaru → krok Zakończenie → sekcja webhooka rejestracji, albo
- Ustawienia → Integracje → Webhooki → sekcja API rejestracji / dokumentacja.
URL ma postać:
https://webivio.com/api/public/registration-webhook?webinarId={uuid-webinaru}&token={sekret}
webinarId— UUID webinarutoken— sekret per webinar (registrationWebhookToken) w query (brak Bearer / API key konta)
Pełna dokumentacja interaktywna w panelu: /auth/settings/integrations/registration-api (możesz wkleić swój URL z tokenem).
Endpoint
| Method | POST (także OPTIONS dla CORS) |
| Path | /api/public/registration-webhook |
| Auth | Query: webinarId + token |
| Content-Type | application/json |
| CORS | Access-Control-Allow-Origin: * |
Body — jeden uczestnik
Wymagane: email oraz dokładnie jeden sposób wskazania terminu.
| Pole | Wymagane | Aliasy | Opis |
|---|---|---|---|
email | Tak | buyer_email, customer_email, e-mail, mail | E-mail uczestnika |
name | Nie | first_name, firstName, imie | Imię |
surname | Nie | last_name, lastName, nazwisko | Nazwisko |
phone | Nie | phone_number, phoneNumber, telefon | Telefon |
selectedDate | Tak* | selected_date, webinarDate, date | Termin ISO z offsetem (preferowane) |
instanceId | Tak* | instance_id | UUID istniejącej instancji |
instanceDate + instanceTime | Tak* | instance_date, instance_time | YYYY-MM-DD + HH:mm |
userTimezone | Nie | user_timezone, timezone, timeZone | np. Europe/Warsaw |
utm_source itd. | Nie | camelCase (utmSource…) | UTM / kampania |
urlParameters, referrer | Nie | snake_case | Dodatkowy kontekst |
*Wybierz jeden wariant terminu.
Przykład (single)
{
"email": "jan@example.com",
"name": "Jan",
"surname": "Kowalski",
"phone": "+48123456789",
"selectedDate": "2026-07-10T18:00:00+02:00",
"userTimezone": "Europe/Warsaw",
"utm_source": "make",
"utm_campaign": "kampania-lipiec"
}
Body — wiele uczestników (bulk)
{
"participants": [
{
"email": "anna@example.com",
"name": "Anna",
"selectedDate": "2026-07-10T18:00:00+02:00"
},
{
"email": "bartek@example.com",
"name": "Bartek",
"instanceId": "uuid-istniejacej-instancji-webinaru"
}
]
}
Limit: max 50 uczestników w jednym żądaniu.
Odpowiedź sukcesu (single, HTTP 200)
{
"success": true,
"participantId": "550e8400-e29b-41d4-a716-446655440000",
"accessCode": "a1b2c3d4",
"instanceId": "660e8400-e29b-41d4-a716-446655440001",
"playerUrl": "https://player.webivio.com/start/?code=a1b2c3d4"
}
Odpowiedź bulk (HTTP 200 przy poprawnym żądaniu)
{
"success": true,
"summary": { "success": 1, "failed": 1 },
"results": [
{
"email": "anna@example.com",
"success": true,
"participantId": "…",
"accessCode": "…",
"instanceId": "…",
"playerUrl": "…"
},
{
"email": "zly@example.com",
"success": false,
"error": "INVALID_EMAIL"
}
]
}
success na poziomie root jest true, gdy przynajmniej jedna rejestracja się udała.
Kody błędów
| HTTP | Znaczenie |
|---|---|
| 400 | Brak emaila, zły JSON, brak terminu, pusty / za duży participants |
| 403 | Zły token lub webinar nieaktywny |
| 404 | Brak webinaru / instancji |
| 409 | Ten e-mail jest już zapisany na wybrany termin |
| 429 | Limit: RATE_LIMIT_EXCEEDED (+ nagłówek Retry-After) |
| 500 | Błąd serwera |
Domyślne limity (per webinar): 50 żądań / minutę, 500 / godzinę.
Przykłady wywołań
curl
curl -X POST \
"https://webivio.com/api/public/registration-webhook?webinarId=YOUR_WEBINAR_ID&token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{"email":"jan@example.com","name":"Jan","selectedDate":"2026-07-10T18:00:00+02:00"}'
PowerShell
$body = @{
email = "jan@example.com"
name = "Jan"
selectedDate = "2026-07-10T18:00:00+02:00"
} | ConvertTo-Json
Invoke-RestMethod `
-Method Post `
-Uri "https://webivio.com/api/public/registration-webhook?webinarId=YOUR_WEBINAR_ID&token=YOUR_TOKEN" `
-ContentType "application/json" `
-Body $body
Zapier (Zapier → Webivio)
- Skopiuj URL webhooka rejestracji z panelu Webivio (z
webinarIditoken). - W Zapierze: akcja Webhooks by Zapier → POST (albo Code, jeśli budujesz JSON ręcznie).
- URL = URL z Webivio.
- Payload Type: JSON.
- Zmapuj pola z poprzedniego kroku (np. Typeform / Google Sheets →
email,name,selectedDate).
Make: HTTP → Make a request → POST na ten sam URL z body JSON.
Po sukcesie Webivio zachowa się jak po zapisie z formularza (e-maile / SMS / CRM wg ustawień webinaru) i może wysłać outbound webinar.registration.created.
Bezpieczeństwo
- Traktuj
tokenjak hasło — nie commituj go do repozytoriów publicznych. - URL z tokenem wystarczy do zapisu na dany webinar; nie udostępniaj go publicznie w front-endzie bez kontroli.
- Rotacja tokenu w UI może być ograniczona — jeśli podejrzewasz wyciek, skontaktuj się ze wsparciem lub wygeneruj nowy webinar / token wg aktualnych opcji w panelu.
Rejestracja na serię webinarów
Ten sam wzorzec (token w URL, single/bulk, rate limit), ale bez wyboru terminu — Webivio wylicza sesje z harmonogramu serii (FIXED / ROLLING).
Gdzie wziąć URL
- Kreator serii → krok Zakończenie → sekcja webhooka rejestracji, albo
- Dashboard serii → Linki → sekcja webhooka rejestracji.
https://webivio.com/api/public/series-registration-webhook?seriesId={uuid-serii}&token={sekret}
seriesId— UUID seriitoken— sekret per seria (registrationWebhookToken)
Endpoint
| Method | POST (także OPTIONS dla CORS) |
| Path | /api/public/series-registration-webhook |
| Auth | Query: seriesId + token |
| Content-Type | application/json |
Body — jeden uczestnik
Wymagane: email. Termin webinaru (selectedDate / instanceId) nie jest wymagany — harmonogram serii liczy się automatycznie.
Opcjonalnie: firstSessionDate (YYYY-MM-DD w strefie uczestnika). Gdy seria ma włączony wybór terminu pierwszej sesji (allowFirstSessionChoice), pole jest wymagane i musi być jedną z dostępnych przyszłych dat day-1. Bez pola (lub gdy wybór jest wyłączony) serwer sam wybiera najbliższy slot.
{
"email": "jan@example.com",
"name": "Jan",
"surname": "Kowalski",
"phone": "+48123456789",
"userTimezone": "Europe/Warsaw",
"firstSessionDate": "2026-07-14",
"utm_source": "make",
"utm_campaign": "kampania-seria"
}
Body — bulk
{
"participants": [
{ "email": "anna@example.com", "name": "Anna" },
{ "email": "bartek@example.com", "name": "Bartek", "userTimezone": "Europe/Warsaw" }
]
}
Limit: max 50 uczestników w jednym żądaniu. Rate limit jak przy webinarze: 50/min, 500/h (per seria).
Odpowiedź sukcesu (single)
{
"success": true,
"seriesRegistrationId": "550e8400-e29b-41d4-a716-446655440000",
"redirectUrl": "https://webivio.com/series-thankyou-page/…",
"sessions": [
{
"sortOrder": 1,
"participantId": "…",
"startTime": "2026-07-10T16:00:00.000Z",
"accessCode": "a1b2c3d4",
"playerUrl": "https://player.webivio.com/start/?code=a1b2c3d4"
}
]
}
Po sukcesie Webivio zachowa się jak po zapisie z formularza serii (mail potwierdzający serii, CRM z webinaru dnia 1, outbound webinar.registration.created dla dnia 1 z polami series_id / series_registration_id).
Wyrejestrowanie z serii
Ten sam token (registrationWebhookToken) i auth w query (seriesId + token), inny path:
https://webivio.com/api/public/series-unregistration-webhook?seriesId={uuid-serii}&token={sekret}
| Method | POST (także OPTIONS dla CORS) |
| Path | /api/public/series-unregistration-webhook |
| Auth | Query: seriesId + token (jak rejestracja) |
| Content-Type | application/json |
Nie wymaga statusu ACTIVE serii — można wyrejestrować także po zakończeniu serii.
Body — jeden uczestnik
Wymagane: email (aliasy: buyer_email, customer_email itd.).
{
"email": "jan@example.com"
}
Body — bulk
{
"participants": [
{ "email": "anna@example.com" },
{ "buyer_email": "bartek@example.com" }
]
}
Limit: max 50 na request. Rate limit jak przy rejestracji serii: 50/min, 500/h.
Odpowiedź — sukces (HTTP 200)
{
"success": true,
"unregistered": true,
"email": "jan@example.com",
"seriesRegistrationId": "550e8400-e29b-41d4-a716-446655440000",
"removedParticipantCount": 3
}
Odpowiedź — email niezapisany (HTTP 200, idempotentnie)
{
"success": true,
"unregistered": false,
"email": "jan@example.com",
"code": "NOT_REGISTERED"
}
Usuwa rejestrację serii i uczestników ze wszystkich dni (hard delete). Nie wysyła maili ani outbound webhooków.
Zobacz też
- Webhooki outbound
- Panel:
/auth/settings/integrations/registration-api
Pomysły na przyszłość (nieprodukcyjne)
Na razie API obejmuje zapis uczestnika / serii (single/bulk). Rozważane rozszerzenia (bez dat):
- klucz API na poziomie konta (Bearer) zamiast tylko tokenu w query
- rotacja tokenu w UI
- GET lista / status uczestników
- aktualizacja danych uczestnika
- nagłówek
Idempotency-Key
To nie są obietnice produktu — tylko kierunki, które zbieramy od użytkowników integracji.
Idempotentność, strefy i 409
Endpoint nie obsługuje nagłówka Idempotency-Key. Nie zakładaj, że ponowienie po timeout jest bezpieczne: zapisuj wynik po swojej stronie i nie wysyłaj automatycznie równoległych retry.
Kod 409 (DUPLICATE_REGISTRATION) oznacza, że ten sam e-mail jest już zapisany na tę samą instancję webinaru. Nie oznacza, że e-mail jest globalnie zablokowany w całym webinarze lub serii. API nie aktualizuje wtedy istniejącego rekordu.
selectedDate i userTimezone nie konkurują ze sobą: przy nowym systemie stref są używane razem. Jeśli selectedDate ma offset, kod przelicza jego godzinę do userTimezone; jeśli offsetu nie ma, traktuje datę i godzinę jako lokalne w userTimezone. Wysyłaj zgodne wartości, najlepiej ISO z offsetem i odpowiadającą mu strefę IANA.