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).

All API docs

Back to home