Hibakódok
Hibakódok, újrapróbálhatóság és hibakezelési útmutató.
Áttekintés#
A Bokko Public API minden válasza egységes boríték (envelope) formátumot használ, függetlenül attól, hogy a kérés sikeres volt-e vagy sem. A hibakezelés egyetlen szabálya:
- Mindig az
error.codemező alapján ágazz el - Soha ne értelmezd az
error.messageszövegét programozottan
error.message mező értéke bármikor változhat, és lokalizált (magyar nyelvű) lehet. Ne építs rá logikát -- kizárólag az error.code mező stabil és szerződéses.Válasz formátum#
Sikeres válasz#
{ ... } placeholder, nem érvényes JSON. A tényleges data mező tartalma endpointonként eltér; konkrét példákért lásd a Gyors indulás oldalt.{
"ok": true,
"data": { ... },
"meta": { "requestId": "req_01HX...", "v": "1" }
}Hibaválasz#
{
"ok": false,
"error": {
"code": "booking.slot_unavailable",
"message": "A kiválasztott időpont nem elérhető.",
"retryable": false,
"details": {
"requestedDate": "2026-04-05",
"requestedStartTime": "10:00",
"nextAvailableStartTime": "10:45"
}
},
"meta": { "requestId": "req_01HX...", "v": "1" }
}A details mező opcionális, és hibakód-specifikus struktúrát tartalmaz. Csak akkor van jelen, ha a hiba további kontextust igényel.
Hibakód struktúra#
A hibakódok {domain}.{reason} formátumot követnek:
| Domain | Példa | Leírás |
|---|---|---|
auth | auth.invalid_key | Hitelesítési és jogosultsági hibák |
booking | booking.slot_unavailable | Foglalási logika hibák |
request | request.invalid_input | Bemeneti validációs és kérési hibák |
rate_limit | rate_limit.exceeded | Kéréslimit túllépés |
idempotency | idempotency.payload_mismatch | Idempotencia-kulcs ütközés |
service | service.not_found | Erőforrás nem található |
internal | internal.error | Belső rendszerhiba (5xx) |
A code mező stabil -- az API verziójának élettartama alatt nem változik. Az message mező kizárólag emberi olvasásra szánt.
Újrapróbálhatóság#
Minden hibaválasz tartalmaz egy retryable boolean mezőt, amely jelzi, hogy a kérés változtatás nélkül újraküldhető-e.
| Hibakód | retryable | Teendő |
|---|---|---|
rate_limit.exceeded | true | Várd meg a Retry-After fejlécben jelzett időt, majd próbáld újra |
idempotency.request_in_progress | true | Az eredeti kérés még feldolgozás alatt áll -- várd meg, majd próbáld újra |
internal.error (5xx) | true | Belső hiba — exponenciális visszalépéssel próbáld újra; mellékeld a requestId-t |
| Minden egyéb | false | Javítsd a kérést, ne próbáld újra vakon |
Exponenciális visszalépés (exponential backoff):
1. kísérlet: azonnali
2. kísérlet: 1s várakozás
3. kísérlet: 2s várakozás
4. kísérlet: 4s várakozás
(max 3 újrapróbálás)Ha a válasz tartalmaz Retry-After fejlécet, annak értéke élvez elsőbbséget a backoff logikával szemben.
Hibakeresés#
Minden válasz tartalmaz egy meta.requestId mezőt, amely egyedileg azonosítja a kérést.
requestId-t mindig mentsd el és mellékeld a support kérésekhez. Ez teszi lehetővé a kérés pontos visszakövetését a rendszerben.A requestId segítségével:
- Korreláció a webhook kézbesítési naplókkal
- Pontos hibaazonosítás support kérés esetén
- Időrendi rekonstrukció több kérés között
Gyakori HTTP státuszkódok#
| Státusz | Jelentés | Javasolt lépés |
|---|---|---|
400 | Érvénytelen bemenet vagy séma hiba | Ellenőrizd a kérés törzsét a details mező alapján; javítsd és próbáld újra |
401 | Érvénytelen vagy hiányzó API kulcs | Ellenőrizd a kulcs formátumát (bk_live_...) és státuszát a dashboardon |
403 | Nincs jogosultság | Ellenőrizd a kulcs capability halmazát és a salonSlug egyezést |
404 | Az erőforrás nem található | Ellenőrizd az URL-t és az erőforrás azonosítóját |
409 | Ütközés | Ellenőrizd a foglalás állapotát vagy az időpont elérhetőségét |
429 | Kéréslimit túllépés | Tartsd be a Retry-After fejlécet, csökkentsd a kérésgyakoriságot |
500 | Belső hiba | Nem a te hibád -- próbáld újra később, vagy jelezd a requestId-vel |
Hibakód katalógus#
Hitelesítési hibák (auth.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
auth.invalid_key | 401 | ❌ Nem | Hiányzó vagy érvénytelen API kulcs |
auth.insufficient_capability | 403 | ❌ Nem | A kulcs nem rendelkezik a szükséges capability-vel Details: { required, granted } |
auth.scope_mismatch | 403 | ❌ Nem | A salonSlug nem egyezik a kulcs tenant scope-jával |
auth.plan_insufficient | 403 | ❌ Nem | Az aktív előfizetés nem tartalmazza a Public API hozzáférést (Pro csomag szükséges) |
Kérési hibák (request.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
request.invalid_input | 400 | ❌ Nem | Séma validáció sikertelen Details: { fieldErrors: [{ field, reason }] } |
request.invalid_cursor | 400 | ❌ Nem | Érvénytelen vagy lejárt cursor |
request.missing_idempotency_key | 400 | ❌ Nem | Idempotency-Key header hiányzik |
request.not_found | 404 | ❌ Nem | Az endpoint nem létezik |
request.method_not_allowed | 405 | ❌ Nem | Nem engedélyezett HTTP metódus |
Foglalási hibák (booking.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
booking.slot_unavailable | 409 | ❌ Nem | A kért időpont már nem elérhető Details: { requestedDate, requestedStartTime, nextAvailableStartTime } |
booking.not_found | 404 | ❌ Nem | Foglalás nem található |
booking.invalid_transition | 409 | ❌ Nem | A foglalás terminális állapotban van Details: { currentStatus, attemptedTransition } |
booking.booking_disabled | 409 | ❌ Nem | Online foglalás nincs engedélyezve |
booking.booking_restricted | 409 | ❌ Nem | Foglalás átmenetileg korlátozva |
booking.service_pricing_changed | 409 | ❌ Nem | A szolgáltatás ára változott a megerősítés óta — kérj friss listát Details: { currentPricingVersion } |
Idempotencia hibák (idempotency.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
idempotency.payload_mismatch | 409 | ❌ Nem | Ugyanaz a kulcs, de eltérő payload |
idempotency.request_in_progress | 503 | ✅ Igen | A kérés még feldolgozás alatt áll |
Rate limit (rate_limit.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
rate_limit.exceeded | 429 | ✅ Igen | Rate limit túllépve Details: { retryAfterSeconds } |
Elérhetőség (availability.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
availability.date_range_too_wide | 400 | ❌ Nem | Dátumtartomány túl széles Details: { maxDays: 31 } |
Szolgáltatás (service.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
service.not_found | 404 | ❌ Nem | Ismeretlen serviceId |
service.unavailable | 409 | ❌ Nem | A szolgáltatás jelenleg nem elérhető (deactivated vagy archive-ban) Details: { serviceId } |
service.not_bookable | 409 | ❌ Nem | A szolgáltatás nem online foglalható (onlineBookable=false) Details: { serviceId } |
Szolgáltató (salon.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
salon.not_found | 404 | ❌ Nem | Szolgáltató nem található |
Webhook (webhook.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
webhook.not_found | 404 | ❌ Nem | Webhook konfiguráció nem található |
Előfizetés (subscription.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
subscription.not_found | 404 | ❌ Nem | Az előfizetés még nem aktivált (pre-activation állapot, nem kliens hiba) |
subscription.snapshot_missing | 500 | ❌ Nem | Belső invariáns sérülés — szerver-oldali alert |
Belső hiba (internal.*)
| Kód | HTTP | Retryable | Leírás |
|---|---|---|---|
internal.error | 500 | ✅ Igen | Belső szerverhiba — generic fallback. Próbáld újra később, vagy jelezd a requestId-vel. |