API rejestracji uczestników

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

  1. Kreator webinaru → krok Zakończenie → sekcja webhooka rejestracji, albo
  2. Ustawienia → Integracje → Webhooki → sekcja API rejestracji / dokumentacja.

URL ma postać:

https://webivio.com/api/public/registration-webhook?webinarId={uuid-webinaru}&token={sekret}
  • webinarId — UUID webinaru
  • token — 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

MethodPOST (także OPTIONS dla CORS)
Path/api/public/registration-webhook
AuthQuery: webinarId + token
Content-Typeapplication/json
CORSAccess-Control-Allow-Origin: *

Body — jeden uczestnik

Wymagane: email oraz dokładnie jeden sposób wskazania terminu.

PoleWymaganeAliasyOpis
emailTakbuyer_email, customer_email, e-mail, mailE-mail uczestnika
nameNiefirst_name, firstName, imieImię
surnameNielast_name, lastName, nazwiskoNazwisko
phoneNiephone_number, phoneNumber, telefonTelefon
selectedDateTak*selected_date, webinarDate, dateTermin ISO z offsetem (preferowane)
instanceIdTak*instance_idUUID istniejącej instancji
instanceDate + instanceTimeTak*instance_date, instance_timeYYYY-MM-DD + HH:mm
userTimezoneNieuser_timezone, timezone, timeZonenp. Europe/Warsaw
utm_source itd.NiecamelCase (utmSource…)UTM / kampania
urlParameters, referrerNiesnake_caseDodatkowy 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

HTTPZnaczenie
400Brak emaila, zły JSON, brak terminu, pusty / za duży participants
403Zły token lub webinar nieaktywny
404Brak webinaru / instancji
409Ten e-mail jest już zapisany na wybrany termin
429Limit: RATE_LIMIT_EXCEEDED (+ nagłówek Retry-After)
500Błą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)

  1. Skopiuj URL webhooka rejestracji z panelu Webivio (z webinarId i token).
  2. W Zapierze: akcja Webhooks by Zapier → POST (albo Code, jeśli budujesz JSON ręcznie).
  3. URL = URL z Webivio.
  4. Payload Type: JSON.
  5. 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 token jak 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

  1. Kreator serii → krok Zakończenie → sekcja webhooka rejestracji, albo
  2. Dashboard serii → Linki → sekcja webhooka rejestracji.
https://webivio.com/api/public/series-registration-webhook?seriesId={uuid-serii}&token={sekret}
  • seriesId — UUID serii
  • token — sekret per seria (registrationWebhookToken)

Endpoint

MethodPOST (także OPTIONS dla CORS)
Path/api/public/series-registration-webhook
AuthQuery: seriesId + token
Content-Typeapplication/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}
MethodPOST (także OPTIONS dla CORS)
Path/api/public/series-unregistration-webhook
AuthQuery: seriesId + token (jak rejestracja)
Content-Typeapplication/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ż

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.