Driver-side (cisternero) operations: going online, performance and earnings stats,
discovering nearby orders, and the driver's own order history and receipts. Paths are
relative to the /api/v1 prefix; every route requires
Authorization: Bearer {token} and the DRIVER role.
See Common errors. The customer-facing order flow lives under Orders; see also the order lifecycle and driver wallet & cash debt.
| Method | URI | Role | Description |
|---|---|---|---|
GET |
/drivers/me/stats |
DRIVER | Earnings stats (week / month / all-time) |
GET |
/driver/stats |
DRIVER | Performance stats by period (+ rating) |
GET |
/driver/surplus |
DRIVER | My surplus listings with status |
GET |
/driver/available-orders |
DRIVER | Nearby broadcasting orders |
POST |
/driver/online |
DRIVER | Go online / offline |
GET |
/driver/orders/active |
DRIVER | My current active order |
GET |
/driver/orders/{orderId}/receipt |
DRIVER | Driver receipt for a delivered order |
GET |
/driver/orders |
DRIVER | My order history (cursor) |
Endpoints that resolve the driver from the token return 404 DriverNotFound when the
caller has no driver profile. Money fields end in _usd (decimal).
Aggregated delivery stats over fixed windows, plus the all-time totals and the driver-bonus counters.
Response 200
{
"week": { "trips": 8, "liters": 40000, "earningsUSD": 130.0, "solidaryUSD": 1.3 },
"month": { "trips": 32, "liters": 160000, "earningsUSD": 520.0, "solidaryUSD": 5.2 },
"allTime": {
"trips": 120,
"liters": 600000,
"solidaryUSD": 19.5,
"bonusQualifyingTrips": 45,
"bonusMinReceives": 40
}
}
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "DriverNotFound" } |
The caller has no driver profile |
Performance for a single period, with the driver's rating. acceptance_rate is
currently always null.
Query
| Field | Type | Required | Rules |
|---|---|---|---|
period |
string | no | day, week, month, total, or all; defaults to all |
Response 200 — for a specific period (e.g. ?period=week):
{
"rating": { "average": 4.8, "total": 96 },
"acceptance_rate": null,
"period": "week",
"stats": { "trips": 8, "liters": 40000, "earningsUSD": 130.0, "solidaryUSD": 1.3 },
"previous": { "trips": 6, "liters": 30000, "earningsUSD": 98.0, "solidaryUSD": 0.98 }
}
With period=all, the response instead carries day, week, month, and total
breakdowns side by side. previous (a comparison window) is omitted for
period=total.
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "DriverNotFound" } |
The caller has no driver profile |
All of the caller's surplus listings (active, reserved, expired, cancelled) with a
status. See Surplus for the listing shape.
Response 200
{
"listings": [
{
"id": 5,
"available_liters": 5000,
"remaining_liters": 0,
"price_per_liter_usd": 0.02,
"total_price_usd": 100.0,
"address": "Av. Principal, Las Mercedes",
"expires_at": "2026-06-26T14:00:00+00:00",
"status": "RESERVADA"
}
]
}
status is one of ACTIVA, RESERVADA, EXPIRADA, or CANCELADA.
Nearby BROADCASTING orders the driver can still serve, ordered by distance. Requires
the driver to be ACTIVE and online.
Query
| Field | Type | Required | Rules |
|---|---|---|---|
latitude |
number | yes | between −90 and 90 |
longitude |
number | yes | between −180 and 180 |
Response 200
{
"items": [
{
"id": 42,
"address": "Av. Principal, Las Mercedes",
"latitude": 10.487,
"longitude": -66.88,
"liters_requested": 5000,
"water_type": "POTABLE",
"base_price_usd": 20.0,
"notes": null,
"distance_km": 1.2,
"expires_at": "2026-06-26T12:05:00+00:00",
"created_at": "2026-06-26T12:00:00+00:00"
}
]
}
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "DriverNotFound" } |
The caller has no driver profile |
403 |
{ "error": "DriverNotActive", "message": "…" } |
Driver status is not ACTIVE |
403 |
{ "error": "DriverOffline", "message": "Debe estar online." } |
Driver is offline |
Toggles the driver online or offline. Going online requires location and a liters
declaration, and checks that the driver is ACTIVE, under the cash-debt cap, and not
exceeding the vehicle's capacity.
Request body
| Field | Type | Required | Rules |
|---|---|---|---|
online |
boolean | yes | — |
latitude |
number | conditional | required when online=true; between −90 and 90 |
longitude |
number | conditional | required when online=true; between −180 and 180 |
liters |
integer | conditional | required when online=true; ≥ 1 |
Response 200
{
"driver": {
"id": 3,
"isOnline": true,
"availableLiters": 5000,
"remainingLiters": 5000,
"currentLat": 10.49,
"currentLng": -66.85,
"lastLocationAt": "2026-06-26T11:55:00+00:00"
}
}
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "DriverNotFound" } |
The caller has no driver profile |
403 |
{ "error": "DriverNotActive", "message": "…" } |
Driver status is not ACTIVE |
403 |
{ "error": "DebtExceedsLimit", "message": "…", "cashDebtUsd": 25.0, "cashDebtCapUsd": 20.0 } |
Cash debt exceeds the cap |
422 |
{ "error": "NoVehicle", "message": "…" } |
No vehicle with a registered capacity |
422 |
{ "error": "LitersExceedCapacity", "message": "…", "capacityLiters": 5000 } |
Declared liters exceed the tank capacity |
The driver's current active order, or null. The payload is the order in the DRIVER
view (see Orders → the order object); the
delivery_pin is hidden until the order is paid (CONFIRMED/IN_PROGRESS/ARRIVED).
Response 200 — { "order": { … } } or { "order": null }.
The driver's receipt for a delivered order they served — the driver-side money split only (no client amounts).
Response 200
{
"receipt": {
"order_id": 42,
"status": "DELIVERED",
"delivered_at": "2026-06-26T12:40:00+00:00",
"liters_requested": 5000,
"actual_liters": 5000,
"water_type": "POTABLE",
"payment_method": "CASH_USD",
"breakdown": {
"driver_gross_usd": 16.4,
"driver_solidary_usd": 0.16,
"driver_receives_usd": 16.24
},
"client": { "id": 1, "name": "Ana Martínez", "phone": "+584241000001" }
}
}
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "DriverNotFound" } |
The caller has no driver profile |
404 |
{ "error": "OrderNotFound" } |
Unknown order |
403 |
{ "error": "Forbidden" } |
The order was not served by this driver |
409 |
{ "error": "OrderNotDelivered", "message": "…" } |
Order not delivered yet |
Cursor-paginated history of the driver's orders, newest first. See Pagination → cursor-based.
Query
| Field | Type | Required | Rules |
|---|---|---|---|
status |
string | no | one of WAITING_FOR_PAYMENT, CONFIRMED, IN_PROGRESS, ARRIVED, DELIVERED, CANCELLED, EXPIRED |
date_from |
date | no | filters created_at ≥ |
date_to |
date | no | after or equal to date_from; filters created_at ≤ |
limit |
integer | no | 1–100; defaults to 25 |
cursor |
string | no | opaque cursor from next_cursor |
Response 200
{
"items": [
{
"id": 42,
"status": "DELIVERED",
"liters_requested": 5000,
"water_type": "POTABLE",
"address": "Av. Principal, Las Mercedes",
"driver_receives_usd": 16.24,
"payment_method": "CASH_USD",
"client": { "id": 1, "name": "Ana Martínez" },
"created_at": "2026-06-26T12:00:00+00:00",
"delivered_at": "2026-06-26T12:40:00+00:00"
}
],
"next_cursor": "eyJpZCI6NDF9",
"has_more": true
}
Errors
| Status | Body | When |
|---|---|---|
404 |
{ "error": "DriverNotFound" } |
The caller has no driver profile |
# Go online with 5000 L at the current location
curl -X POST /api/v1/driver/online \
-H "Authorization: Bearer {driver_token}" \
-H "Content-Type: application/json" \
-d '{"online": true, "latitude": 10.49, "longitude": -66.85, "liters": 5000}'
# Discover nearby broadcasting orders
curl "/api/v1/driver/available-orders?latitude=10.49&longitude=-66.85" \
-H "Authorization: Bearer {driver_token}"
# This week's performance
curl "/api/v1/driver/stats?period=week" -H "Authorization: Bearer {driver_token}"