Admin orders

Browse live and archived orders, export them, read full detail, and force status changes. 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 and the order lifecycle.

Admins see the full order record with all money fields.

Endpoints

Method URI Access Description
GET /admin/orders Admin Live orders (cursor-paginated)
GET /admin/orders/export Admin Export filtered orders as CSV
GET /admin/orders/stats Admin Status counters for the dashboard cards
GET /admin/orders/archived Admin Archived order history (cursor-paginated)
GET /admin/orders/{orderId} Admin Full order detail, timeline & chat
PATCH /admin/orders/{orderId}/force-status Admin Force an order into another status

GET /admin/orders

Cursor-paginated live orders (archived excluded), newest first. See Pagination → cursor-based.

Query

Field Type Required Rules
status string no one order status (BROADCASTING … EXPIRED)
date_from date no filter created_at >=
date_to date no filter created_at <=; >= date_from
driver_id integer no filter by assigned driver
payment_method string no filter by payment method code
limit integer no 1–100, default 25
cursor string no opaque cursor from next_cursor

Response 200

{
  "items": [
    {
      "id": 42,
      "status": "IN_PROGRESS",
      "client": { "id": 1, "name": "Ana MartĂ­nez", "phone": "+584241000001" },
      "driver": { "id": 3, "name": "Carlos RodrĂ­guez", "phone": "+584241001001" },
      "liters": 5000,
      "amount_usd": 20.2,
      "payment_method": "CASH_USD",
      "address": "Av. Principal, Las Mercedes",
      "created_at": "2026-06-26T12:00:00+00:00"
    }
  ],
  "next_cursor": "eyJpZCI6NDF9",
  "has_more": true
}

driver is null for unassigned orders.


GET /admin/orders/export

Streams the filtered orders as a CSV download (Content-Type: text/csv); there is no JSON body. Accepts the same filters as the list except limit/cursor. Columns: ID, Status, Client Name, Driver Name, Liters, Price (USD), Payment Method, Created At, Delivered At, Cancelled At, Cancelled By.

Errors

Status Body When
422 { "error": "TooManyResults", "message": "…" } More than 10,000 rows match the filters

GET /admin/orders/stats

Status counters over the live (non-archived) set, for the dashboard cards.

Response 200

{
  "active": 13,
  "today": 8,
  "delivered": 30,
  "cancelled_expired": 4,
  "broadcasting": 1,
  "waiting_for_payment": 1,
  "confirmed": 3,
  "in_progress": 5,
  "arrived": 2
}

active covers all non-archived orders; cancelled_expired covers CANCELLED and EXPIRED orders.


GET /admin/orders/archived

Same shape, filters, and cursor pagination as GET /admin/orders, but over archived orders (terminal orders from previous days).

Response 200 — { "items": [ … ], "next_cursor": "…", "has_more": false }.


GET /admin/orders/{orderId}

Full order detail. The order is the complete record (all money fields), plus a timeline and the in-order chat.

Response 200

{
  "order": {
    "id": 42,
    "status": "DELIVERED",
    "client_id": 1,
    "driver_id": 3,
    "address": "Av. Principal, Las Mercedes",
    "liters_requested": 5000,
    "actual_liters": 5000,
    "payment_method": "CASH_USD",
    "base_price_usd": 20.0,
    "client_pays_usd": 20.2,
    "aguita_revenue_usd": 3.6,
    "driver_receives_usd": 16.24,
    "solidary_fund_usd": 0.36,
    "delivery_pin": "1234"
  },
  "timeline": [
    { "event": "CREATED", "at": "2026-06-26T12:00:00+00:00" },
    { "event": "CONFIRMED", "at": "2026-06-26T12:05:00+00:00" },
    { "event": "DELIVERED", "at": "2026-06-26T12:40:00+00:00" }
  ],
  "chat": [
    {
      "id": 1,
      "sender_id": 1,
      "sender_role": "client",
      "body": "¿Cuánto falta?",
      "created_at": "2026-06-26T12:20:00+00:00"
    }
  ]
}

A CANCELLED timeline entry also carries by and reason. See Business → money breakdown.

Errors

Status Body When
404 { "error": "OrderNotFound" } No order with that id

PATCH /admin/orders/{orderId}/force-status

Forces the order into a new status. Only lifecycle-valid transitions are allowed; terminal states (DELIVERED, CANCELLED, EXPIRED) cannot transition.

Request body

Field Type Required Rules
status string yes target order status
reason string yes 10–500 chars

Response 200

{
  "order": {
    "id": 42,
    "status": "DELIVERED",
    "accepted_at": "2026-06-26T12:02:00+00:00",
    "confirmed_at": "2026-06-26T12:05:00+00:00",
    "paid_at": "2026-06-26T12:05:00+00:00",
    "in_progress_at": "2026-06-26T12:10:00+00:00",
    "arrived_at": "2026-06-26T12:35:00+00:00",
    "delivered_at": "2026-06-26T12:40:00+00:00",
    "cancelled_at": null,
    "delivery_pin": "1234",
    "side_effects": { "delivery_pin_generated": true }
  },
  "audit_entry": {
    "from_status": "ARRIVED",
    "to_status": "DELIVERED",
    "reason": "ConfirmaciĂłn manual de entrega",
    "admin_id": 1,
    "created_at": "2026-06-29T12:00:00+00:00"
  }
}

side_effects may include delivery_pin_generated and/or payment_cancelled.

Errors

Status Body When
404 { "error": "OrderNotFound" } No order with that id
422 { "error": "InvalidTransition", "message": "…" } Not an allowed status change