GEBETA Guest API
Base URL: https://gebetaexpress.com/api/v1
· Flutter --dart-define=GEBETA_API=https://gebetaexpress.com/api/v1
Guest / Passenger API
Base URL: https://gebetaexpress.com/api/v1
Hotel / PMS partners (ZemenBooking, in-house): see partner-api.md — X-Api-Key auth, no Bearer token.
Primary identity: phone. Same phone may also have a separate rider account.
Full catalog + poll loops: mobile-api.md
Response shape
{ "success": true, "message": "...", "data": {}, "errors": [] }Quick loops
1. GET /bootstrap → poll intervals + endpoint map 2. GET /sync/passenger every ~8s 3. GET /orders/{id}/tracking or GET /orders/status/{pnr} every ~15s while the order is active (poll_after_ms). Stop when poll_after_ms is 0. 4. GET /passenger/orders for the order list; GET /sync/notifications every ~15s; POST /sync/notifications/read when opened 5. Public map: GET /track/{pnr} or website /track/{pnr}
Tracking payload: pickup, dropoff, rider GPS, route.points, progress_percent, eta_minutes, status (DB name) + status_label. Sequential order IDs without Bearer or PNR/token are 401.
Auth, cookie, and status codes: developer.md.
Auth
Login and OTP verify return data.token and set ci_session. Send Authorization: Bearer and keep that cookie on later calls (/favorites, /passenger/orders, /auth/passenger/me). 401 Unauthorized means the token did not arrive (log in again). 422 means phone or password failed validation, not that the session was rejected.
| Method | Path ||--------|------|| POST | /auth/passenger/login || POST | /auth/passenger/otp/request || POST | /auth/passenger/otp/verify || POST | /auth/passenger/register || POST | /auth/passenger/password/reset || POST | /auth/passenger/logout || GET | /auth/passenger/me |Catalog & meal plans
| Method | Path ||--------|------|| GET | /bootstrap || GET | /ping (alias /heartbeat) || GET | /catalog/restaurants || GET | /catalog/home?lat=&lng= | nearby + top rated + sponsored + deals || GET | /catalog/nearby?lat=&lng= || GET | /catalog/top-rated || GET | /catalog/sponsored || GET | /catalog/deals || GET | /catalog/restaurants/{id\|slug} || GET | /catalog/dishes || GET | /search?q= || GET | /search/suggest?q= || GET | /location/suggest?q= || GET | /location/reverse?lat=&lng= || GET | /market || GET | /book || GET | /services || POST | /market/checkout | Bearer || POST | /book | Bearer || POST | /reservations | Bearer || GET | /sync/notifications | Bearer || GET | /notifications | Bearer — alias || GET | /notifications/unread | Bearer || POST | /sync/notifications/read | Bearer || GET | /meal-plans/{id} || GET | /passenger/meal-plan/today | Bearer || GET | /passenger/orders | Bearer || GET | /payments || POST | /orders/quote || POST | /orders/checkout | Bearer or phone || GET | /favorites | Bearer || POST | /favorites/toggle | Bearer || POST | /auth/passenger/profile | Bearer || GET | /sync/passenger | Bearer || GET | /track/{pnr\|token} | public |Bearer: login returns the raw token. The DB stores SHA-256 of that raw value. The same login writes the raw token onto ci_session because the public proxy drops Authorization. CSRF off for /api/v1/*. X-APP-KEY is not required. Docs at /docs/api are public.
Restaurant settlement webhook (not under /api/v1): POST /webhooks/restaurant-payout — see mobile-api.md.