Admin customers

Browse customers and drill into a single customer's order history. 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.

An admin only sees customers who have ordered in their assigned cities.

Endpoints

Method URI Access Description
GET /admin/customers Admin Paginated customer list with spend totals
GET /admin/customers/{customerId} Admin Customer profile, totals & recent orders
POST /admin/customers/{customerId}/credit/adjust Admin Manually credit or debit promotional credit
GET /admin/customers/{customerId}/credit/transactions Admin Paginated promotional credit history
GET /admin/customers/{customerId}/bank-account Admin The customer's saved Pago MĂłvil account
PUT /admin/customers/{customerId}/bank-account Admin Create or replace the saved account
DELETE /admin/customers/{customerId}/bank-account Admin Remove the saved account

GET /admin/customers

Page-paginated customer list (newest first). See Pagination → page-based.

Query

Field Type Required Rules
is_active boolean no filter by the user's active flag
min_spent number no ≥ 0; approximate minimum spend in USD
max_spent number no ≥ 0; approximate maximum spend in USD
q string no ≤ 80 chars; matches name or phone
limit integer no 1–100, default 25
page integer no ≥ 1, default 1

min_spent / max_spent are approximate, not an exact order total.

Response 200

{
  "items": [
    {
      "id": 1,
      "name": "Ana MartĂ­nez",
      "phone": "+584241000001",
      "email": "ana@example.com",
      "is_active": true,
      "total_orders": 12,
      "total_liters_ordered": 36000,
      "total_solidary_usd": 4.2,
      "created_at": "2026-06-01T09:00:00+00:00"
    }
  ],
  "meta": { "total": 137, "per_page": 25, "current_page": 1, "last_page": 6 }
}

GET /admin/customers/{customerId}

Customer profile, lifetime totals, and a page of their orders (newest first).

Query

Field Type Required Rules
limit integer no 1–100, default 10
page integer no ≥ 1, default 1

Response 200

{
  "customer": {
    "id": 1,
    "name": "Ana MartĂ­nez",
    "phone": "+584241000001",
    "email": "ana@example.com",
    "is_active": true,
    "created_at": "2026-06-01T09:00:00+00:00",
    "updated_at": "2026-06-28T18:00:00+00:00"
  },
  "totals": {
    "total_orders": 12,
    "total_liters_ordered": 36000,
    "total_spent_usd": 4.2
  },
  "credit": {
    "anyUSD": 10,
    "ordersUSD": 0,
    "surplusUSD": 5,
    "usableOnOrdersUSD": 10,
    "usableOnSurplusUSD": 15,
    "earnedUSD": 25,
    "redeemedUSD": 10
  },
  "orders": [
    {
      "id": 42,
      "status": "DELIVERED",
      "location_from": { "lat": 10.487, "lng": -66.88, "text": "Av. Principal" },
      "location_to": { "lat": null, "lng": null, "text": null },
      "liters": 5000,
      "price_usd": 20.2,
      "driver": { "id": 3, "name": "Carlos RodrĂ­guez", "phone": "+584241001001" },
      "created_at": "2026-06-26T12:00:00+00:00",
      "completed_at": "2026-06-26T12:40:00+00:00"
    }
  ],
  "meta": { "total": 12, "per_page": 10, "current_page": 1, "last_page": 2 }
}

driver is null for orders that were never assigned. location_to is currently always null-valued. credit has the same shape as GET /credit/me.

Errors

Status Body When
404 { "error": "CustomerNotFound" } No customer (client profile) with that id

POST /admin/customers/{customerId}/credit/adjust

Manually moves one promotional credit bucket.

Request body

Field Type Required Rules
type string yes credit or debit
scope string no ANY, ORDERS or SURPLUS (defaults to ANY)
amount number yes min:0.01, in USD
reason string yes 10–500 chars

Response 200

{
  "transaction": {
    "id": 31,
    "type": "MANUAL_ADJUSTMENT",
    "scope": "ANY",
    "direction": "CREDIT",
    "amount_usd": 5,
    "balance_after_usd": 15,
    "order_id": null,
    "promotion_id": null,
    "description": "credit manual: CortesĂ­a por demora",
    "created_at": "2026-08-27T12:00:00+00:00"
  }
}
Field Type Description
transaction.scope string The bucket that moved
transaction.direction string CREDIT or DEBIT
transaction.amount_usd number Always positive; the sign lives in direction
transaction.balance_after_usd number Balance of that bucket after the movement; a debit may leave it negative

Errors

Status When
401 Missing or invalid admin bearer token
404 CustomerNotFound — no customer with that id
422 Validation failed

GET /admin/customers/{customerId}/credit/transactions

Cursor-paginated promotional credit history, newest first.

Query parameters

Field Type Required Rules
type string No PROMO_GRANT, ORDER_REDEMPTION, ORDER_FORFEIT, ORDER_REFUND or MANUAL_ADJUSTMENT
scope string No ANY, ORDERS or SURPLUS
limit integer No min:1, max:100 (default 25)
cursor string No Cursor from a previous response

Response 200 — { "items": [ {transaction}, … ], "next_cursor": …, "has_more": … }, each item shaped like the transaction above.

Errors

Status When
401 Missing or invalid admin bearer token
404 CustomerNotFound — no customer with that id
422 Validation failed

GET /admin/customers/{customerId}/bank-account

The customer's one saved Pago MĂłvil account, used to pre-fill the refund form.

Response 200

{
  "account": {
    "id": 7,
    "id_number": "V12345678",
    "phone": "04125551234",
    "bank_code": "0102",
    "updated_at": "2026-09-15T14:00:00+00:00"
  }
}

account is null when the customer has no saved account.

Errors

Status When
401 Missing or invalid admin bearer token
404 CustomerNotFound — no customer with that id

PUT /admin/customers/{customerId}/bank-account

Creates the saved account, or replaces it if one exists (one account per customer).

Request body

Field Type Required Rules
idNumber string yes Cédula, regex ^[VEJGP]?\d{6,10}$; normalized to uppercase without separators
phone string yes Venezuelan mobile, regex `^(0
bankCode string yes Exactly 4 digits

Response 200 — { "account": {…} }, shaped like the GET above.

Errors

Status When
401 Missing or invalid admin bearer token
404 CustomerNotFound — no customer with that id
422 Validation failed

DELETE /admin/customers/{customerId}/bank-account

Removes the saved account, if any.

Response 204 — no content.

Errors

Status When
401 Missing or invalid admin bearer token