Admin dashboard

Operational KPIs and chart series for the back-office home screen. Paths are relative to the /api/v1 prefix; these are back-office endpoints requiring an admin token.

Requires an admin bearer token (see Admin auth). Admin only.

See Common errors.

All three endpoints share the same period selector (below). Revenue values are in USD; driver counts are scoped to the admin's assigned cities.

Endpoints

Method URI Access Description
GET /admin/dashboard/kpis Admin Headline metrics with previous-period comparison
GET /admin/dashboard/revenue-week Admin Daily revenue series (with per-method breakdown)
GET /admin/dashboard/orders-distribution Admin Order counts grouped by status

Period selector

Every endpoint accepts these query parameters:

Field Type Required Rules
period string no today (default), yesterday, last_7_days, last_30_days, or custom
from date conditional required when period=custom
to date conditional required when period=custom; >= from

The response always echoes the resolved period, from, and to (as YYYY-MM-DD).


GET /admin/dashboard/kpis

Four headline metrics for the selected period, each compared to the equivalent previous period. Query: see the period selector.

Response 200

{
  "period": "today",
  "from": "2026-06-29",
  "to": "2026-06-29",
  "orders": { "current": 42, "previous": 38, "change_pct": 10.5 },
  "liters": { "current": 210000, "previous": 190000, "change_pct": 10.5 },
  "revenue_usd": { "current": 848.4, "previous": 760.0, "change_pct": 11.6 },
  "active_drivers": { "current": 12, "previous": 12, "change_pct": 0 }
}

Each metric group carries current, previous, and change_pct. change_pct is null when the previous value is 0 (no baseline to compare against). liters counts delivered liters; revenue_usd is revenue from delivered orders.


GET /admin/dashboard/revenue-week

Per-day revenue across the period, including empty days, with a breakdown by payment method. Query: see the period selector.

Response 200

{
  "period": "last_7_days",
  "from": "2026-06-23",
  "to": "2026-06-29",
  "days": [
    {
      "date": "2026-06-23",
      "label": "Lun",
      "revenue_usd": 120.5,
      "breakdown": { "CASH_USD": 80.5, "SYPAGO_DI": 40.0 }
    }
  ]
}

label is a short Spanish weekday (Lun, Mar, …). breakdown keys are payment method codes; the object is empty {} on days with no delivered orders.

Errors

Status Body When
422 { "error": "Period too long (max 90 days)" } The resolved range spans more than 90 days

GET /admin/dashboard/orders-distribution

Order counts grouped by status over the period, returned as a fixed, ordered list of all statuses (zero-filled). Query: see the period selector.

Response 200

{
  "period": "today",
  "from": "2026-06-29",
  "to": "2026-06-29",
  "total": 42,
  "distribution": [
    { "status": "DELIVERED", "label": "Completado", "count": 30 },
    { "status": "IN_PROGRESS", "label": "En Camino", "count": 5 },
    { "status": "ARRIVED", "label": "En Destino", "count": 2 },
    { "status": "CONFIRMED", "label": "Confirmado", "count": 3 },
    { "status": "WAITING_FOR_PAYMENT", "label": "Esperando pago", "count": 1 },
    { "status": "BROADCASTING", "label": "Pendiente", "count": 1 },
    { "status": "COUNTER_OFFERED", "label": "Contraoferta", "count": 0 },
    { "status": "CANCELLED", "label": "Cancelado", "count": 0 },
    { "status": "EXPIRED", "label": "Expirado", "count": 0 }
  ]
}

total is the total number of orders in the period.