API: dispositivos e inventario
Contrato general en Cómo funciona la API.
POST /devices y DELETE /devices/:id exigen el recurso reservado device_provisioning: una key
recibe 403. Todo lo demás —leer, editar, mover, activar/desactivar e inventario— sí está disponible.
Consultar
GET /devices
GET /devices/:id
Query de listado: operationId, businessLine, isActive, type (spring, locker, liquid,
coffee, return), search (nombre, serial o ciudad), page, pageSize (máx. 1000).
Respuesta de un dispositivo (recortada):
{
"id": "665f…d1",
"serial": "ICS595DDE99B",
"name": "Vending Corferias 1",
"businessLine": "vending",
"currency": "COP",
"accountId": "665f…c6",
"operationId": "665f…c7",
"specs": {
"type": "spring",
"brand": "INSSA SNACKS",
"model": "IKA 5 COMBI",
"paymentMethods": { "cashless": true, "cash": false, "card": true }
},
"location": { "country": "Colombia", "city": "Bogotá", "address": "Corferias", "coordinates": null },
"controller": { "serial": "ICS595DDE99B", "status": "online" },
"planogramKind": "physical",
"isActive": true,
"lastTransmission": "2026-08-11T13:58:22.000Z"
}
Editar y mover
PATCH /devices/:id { "name": "…", "location": { … }, "specs": { … } }
PATCH /devices/:id/scope { "operationId": "665f…c8" }
PATCH /devices/:id/deactivate
PATCH /devices/:id/activate
PATCH /devices/:id acepta name, location, specs y peripherals; marca y periféricos solo los
cambia un operador global (403 para el resto).
PATCH /devices/:id/scope mueve el dispositivo a otra operación. Una key solo puede moverlo dentro
de su cuenta; mover a otra cuenta exige nivel cliente o global.
Activar y desactivar responden 204.
Inventario (planograma)
PUT /devices/:id/planogram
PATCH /devices/:id/slots/:selection
POST /devices/:id/slots/:selection/load
DELETE /devices/:id/slots/:selection
Requieren device_inventory:update, que la key tiene.
Reemplazar el planograma completo
PUT /devices/:id/planogram — envía la estructura final: filas y casillas. Sustituye lo que hubiera,
así que lo que no mandes se borra.
{
"kind": "physical",
"rows": [{ "rowId": "R1", "name": "Bandeja 1", "capacity": 12 }],
"slots": [
{
"selection": "11",
"rowId": "R1",
"productId": "665f…b1",
"maxQty": 20,
"minQty": 3,
"currentQty": 12,
"price": 3000
}
]
}
Reglas: cada casilla referencia una fila declarada, la selección es única (mayúsculas y dígitos,
máx. 8) y los módulos de devolución no admiten planograma
(400 devices.planogram_not_applicable).
Ajustar una casilla
PATCH /devices/:id/slots/:selection — campos opcionales, null para limpiar:
| Campo | Tipo | Notas |
|---|---|---|
productId | string | null | null deja la casilla vacía |
maxQty / minQty / currentQty | entero | null | ≥ 0 |
price | entero | null | unidades menores. En cashless el cobro lo reporta el dispositivo |
Reponer
POST /devices/:id/slots/:selection/load — { "productId": "665f…b1", "qty": 20, "price": 3000 }.
Es el endpoint natural del proceso de reabastecimiento: fija producto y cantidad de una vez.
DELETE /devices/:id/slots/:selection vacía la casilla.
Todos devuelven 200 con el dispositivo actualizado (o 204 en el DELETE).
Errores propios: 404 devices.not_found, 404 devices.slot_not_found,
409 devices.slot_conflict, 400 devices.product_mismatch,
400 devices.invalid_planogram_shape, 403 devices.not_visible_to_scope.