GEBETA Rider API
Base URL: https://gebetaexpress.com/api/v1
· Flutter --dart-define=GEBETA_API=https://gebetaexpress.com/api/v1
Rider API
Base URL: https://gebetaexpress.com/api/v1
Primary identity: phone number.
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. The public proxy drops Authorization; the session cookie is what authenticates https://gebetaexpress.com. 401 with message Unauthorized means log in again. 401 Invalid phone or password. is a bad login. 422 means phone or password was missing or too short. 403 means the rider is not approved.
| Method | Path ||--------|------|| POST | /auth/rider/register | { full_name, phone, password, email?, vehicle_type? } pending application || POST | /auth/rider/login | { phone, password } || POST | /auth/rider/otp/request | { phone } || POST | /auth/rider/otp/verify | { phone, code } || POST | /auth/rider/password/reset | OTP request/confirm || POST | /auth/rider/logout | Bearer || GET | /auth/rider/me | Bearer |Delivery operations
| Method | Path | Notes ||--------|------|--------|| POST | /riders/availability | { online: true\|false } || POST | /riders/location | { latitude, longitude, accuracy?, heading?, speed?, source? } — rider_id from Bearer only. Alias: POST /rider/location || GET | /delivery/offers | Ready/dispatching orders (or open offers) || POST | /delivery/{id}/accept | Must be assigned offer / eligible || POST | /auth/rider/orders/{id}/reject | Reject open offer || POST | /delivery/{id}/pickup | Owned order — requires pickup_pod_code / otp (4-digit) → picked_up then auto on_delivery. Alias: POST /auth/rider/orders/{id}/pickup || POST | /delivery/{id}/arrive | Arrive at current stop: assigned→arrived_restaurant (then enter pickup OTP), picked_up/on_delivery→near_customer (then enter delivery POD). Does not skip POD. Alias: POST /auth/rider/orders/{id}/arrive || POST | /auth/rider/orders/{id}/on-the-way | → on_delivery || POST | /delivery/{id}/delivered | Requires pod_code / otp. Alias: POST /auth/rider/orders/{id}/delivered || GET | /auth/rider/history | Delivered/cancelled || GET | /auth/rider/earnings | Week commission || GET | /orders/{id}/tracking | Assigned rider (or admin). Same live payload as passenger tracking. || GET | /track/{pnr} | Public PNR map (optional for rider apps) || GET | /rider/sync | Offers + active job (includes arrived_restaurant); each order has navigation, next_actions, pickup_pod_required / delivery_pod_required |Rider order payload (after accept / arrive / pickup / sync)
{
"status": "arrived_restaurant",
"status_label": "Enter pickup OTP",
"next_action": "pickup",
"next_actions": [
{
"action": "pickup",
"method": "POST",
"path": "/api/v1/delivery/123/pickup",
"label": "Confirm pickup with OTP",
"requires": ["pickup_pod_code"]
}
],
"pickup_pod_required": true,
"pickup_pod_digits": 4,
"delivery_pod_required": false,
"navigation": {
"mode": "pickup",
"lat": 9.03,
"lng": 38.74,
"label": "Restaurant name",
"address": "…",
"maps_url": "https://www.google.com/maps/dir/?api=1&destination=9.03,38.74"
}
}Flow: accept → arrive (restaurant) → pickup { "pickup_pod_code": "1234" } → arrive (customer) → delivered { "pod_code": "5678" }.
POD codes are never returned to the rider app (restaurant/customer hold them).
Wallet
| Method | Path | Notes ||--------|------|--------|| GET | /rider/wallet | Bearer || GET | /rider/wallet/transactions | Bearer || POST | /rider/wallet/topup | { amount } || POST | /rider/wallet/topup/chapa | Chapa checkout || POST | /rider/wallet/topup/telebirr | Telebirr |Riders cannot access arbitrary order IDs — ownership and offer checks are enforced server-side.
Send GPS about every 12 seconds while online with an active job. GET /rider/sync returns gps_every_ms. Stop GPS when the order is terminal (poll_after_ms: 0 on tracking).
Dispatch
Cron command: php spark gebeta:dispatch
- Finds READY/DISPATCHING orders without rider - Ranks eligible online riders by haversine distance within restaurant dispatch_radius_km - Single open offer at a time; expires after dispatch_offer_timeout_sec - After exhausted attempts → status no_driver (not cancelled) - Restaurant can Retry dispatch
Response shape
Same as guest API (success, message, data, errors).