Przejdź do głównej zawartości

Errors

Wszystkie endpointy używają standardowych kodów HTTP. Body błędu to JSON w formacie FastAPI / Pydantic.

Format​

Walidacja Pydantic (422)​

{
"detail": [
{
"loc": ["body", "doctors", 0, "email"],
"msg": "value is not a valid email address",
"type": "value_error.email"
}
]
}

Reszta (400/401/403/404/409/429/500)​

{
"detail": "Slot już zarezerwowany przez innego pacjenta"
}

detail to string PL lub strukturalny obiekt — nigdy stack trace.

Kody HTTP​

KodZnaczenieKiedy
200OKSuccessful read / upsert (zwraca created + updated + errors)
201CreatedBooking, lead, review created
204No ContentDELETE successful (np. slot delete)
400Bad RequestBody prawidłowy ale logika odrzuca (np. slot w przeszłości)
401UnauthorizedBrak / nieprawidłowy / revoked API key
402Payment RequiredSubskrypcja klinki past_due >7d lub cancelled
403ForbiddenKlucz nie ma wymaganego scope, lub patient próbuje akcji clinic_admin
404Not FoundResource nie istnieje, lub cross-clinic (G-DATA-001 zwraca 404 unify)
409ConflictBooking race lost — slot zarezerwował kto inny atomowo
422UnprocessablePydantic walidacja (input format, regex, range)
429Too Many RequestsRate limit (patrz rate limits)
500Server ErrorBug — zgłoś na kontakt@pandoktorek.pl z X-Request-ID z headerów response

Typowe błędy ingest​

422 — external_id puste albo > 120 znaków​

{"detail": [{"loc":["body","doctors",0,"external_id"],"msg":"ensure this value has at least 1 characters"}]}

Fix: każdy item musi mieć stabilne, unikalne external_id (z twojego CRM).

422 — pwz nie pasuje do ^\d{7}$​

{"detail": [{"loc":["body","doctors",0,"pwz"],"msg":"string does not match regex \"^\\d{7}$\""}]}

Fix: PWZ musi być dokładnie 7 cyfr. Jeśli lekarz nie ma PWZ (np. fizjoterapeuta) — przekaż null lub pomiń pole.

422 — phone nie pasuje do regex​

Fix: format E.164 + opcjonalny +, 9-15 cyfr. Przykłady poprawne: +48501234567, 48501234567, 501234567.

422 — services_allowed zawiera nieistniejący external_id​

Fix: najpierw pushuj services, potem slots. Albo pomiń services_allowed — slot będzie dostępny dla wszystkich active services lekarza.

409 — booking race lost​

{"detail": "Slot już zarezerwowany przez innego pacjenta"}

Wystąpiło przy POST /api/v1/bookings. Atomic UPDATE przegrał — inny pacjent zarezerwował ten sam slot pierwszy. Frontend pokazuje toast, prosi o wybór innego slotu.

Idempotency a błędy​

POST /api/v1/clinic/{doctors,services,slots} jest idempotent po (clinic_id, external_id). Re-run tego samego payloadu po błędzie sieciowym (timeout, 502 od Caddy) nie tworzy duplikatów — zwróci created=0, updated=N.

→ Idempotency

Webhook delivery errors​

Twój system odbiera webhook → musi zwrócić 2xx w ciągu 10s. W przeciwnym razie Pandoktorek retry'uje z exponential backoff. Po 5 nieudanych próbach status failed — ręczny retry z panelu klinki.

→ Webhook retry policy

Co przekazać w bug report​

Gdy coś nie działa, prześlij:

  1. Request ID — z headera X-Request-ID w response (każdy request ma)
  2. Czas UTC (np. 2026-05-08T14:32:11Z)
  3. Endpoint + method
  4. Klucz prefix (np. pk_live_a3f8b2c1) — NIE pełen klucz
  5. Status code + detail który dostałeś

→ kontakt@pandoktorek.pl