Reportes de Inventario
Un único endpoint genera cinco tipos de reporte según el parámetro reportType. La forma de la respuesta cambia por completo entre tipos — no asumas un esquema compartido entre reportes.
Endpoint
Genera un reporte del tipo solicitado. Requiere inventory:read.
reportTypestringrequiredinventory, transfers, adjustments, counts o valuation.
startDatestringFecha inicial ISO 8601. Aplica a transfers, adjustments y counts.
endDatestringFecha final ISO 8601.
locationIdstringFiltra por ubicación. Aplica a inventory, adjustments, counts y valuation.
formatstringjson o csv. Ver advertencia abajo — no tiene efecto.
La forma exacta de data/summary depende de reportType — ver el detalle de cada uno debajo. Este ejemplo usa reportType=adjustments:
{
"data": [
{ "id": "adj_01H...", "sku": "CAM-ROJO-M", "adjustmentQuantity": -3, "reason": "damage" }
],
"summary": { "total": 1, "totalQuantityAdjusted": -3, "byReason": { "damage": 1 } }
}
{ "code": "bad-request/missing-type" }
{ "code": "bad-request/invalid-report" }
format no está implementado
El parámetro format se acepta (json o csv) pero no cambia la respuesta: siempre se devuelve JSON, sin importar el valor enviado. No construyas un flujo de exportación CSV asumiendo que este parámetro lo produce.
Toda la respuesta sigue la forma { data, summary }, donde data y summary cambian de estructura según reportType:
reportType=inventory
Snapshot del stock actual, hasta 10,000 registros, filtrado por locationId si se envía. No es un reporte paginado.
{
"data": [
{ "sku": "CAM-ROJO-M", "locationId": "loc_cedis_cdmx", "stock": 137 }
],
"summary": { "totalItems": 1, "locationId": "loc_cedis_cdmx" }
}
reportType=transfers
Transferencias filtradas por fecha (startDate/endDate).
{
"data": [
{ "id": "trf_01H...", "originId": "loc_a", "destinationId": "loc_b", "status": "received" }
],
"summary": { "total": 1, "byStatus": { "pending": 0, "approved": 0, "received": 1, "cancelled": 0 } }
}
reportType=adjustments
Ajustes filtrados por fecha y locationId.
{
"data": [
{ "id": "adj_01H...", "sku": "CAM-ROJO-M", "adjustmentQuantity": -3, "reason": "damage" }
],
"summary": { "total": 1, "totalQuantityAdjusted": -3, "byReason": { "damage": 1 } }
}
reportType=counts
Conteos filtrados por fecha y locationId.
{
"data": [
{ "id": "cnt_01H...", "name": "Conteo cíclico julio", "status": "completed" }
],
"summary": { "total": 1, "byStatus": { "draft": 0, "in_progress": 0, "completed": 1, "cancelled": 0 } }
}
reportType=valuation
Este reporte está roto en producción hoy
data se construye leyendo item.unitCost directamente del documento Inventory — pero el schema canónico de Inventory (Lib/Services/Inventory/src/model/schema.ts) no tiene un campo unitCost. Ese valor siempre es undefined, así que totalValue y averageUnitCost de este reporte son efectivamente 0 para todos los registros. Es funcionalidad muerta sobre la colección base Inventory — no un bug menor de redondeo.
La valuación correcta y activa en producción vive en el subsistema de lotes FIFO: usa GET /inventory/lots/valuation o GET /inventory/lots/sku/{sku}/valuation en su lugar.
{
"data": [
{ "sku": "CAM-ROJO-M", "productName": "Camisa Roja Talla M", "stock": 137, "unitCost": 0, "totalValue": 0, "locationId": "loc_cedis_cdmx" }
],
"summary": { "totalItems": 1, "totalUnits": 137, "totalValue": 0, "averageUnitCost": 0 }
}
Errores
| Código | HTTP | Causa |
|---|---|---|
bad-request/missing-type | 400 | No se envió reportType. |
bad-request/invalid-report | 400 | reportType no es uno de los cinco valores válidos. |
Consulta el Catálogo de Errores para los errores comunes a todo el dominio.
Ejemplos
curl -G https://api.fenicia.io/inventory/reports \
-H "Authorization: Bearer fkapi_tu_api_key" \
--data-urlencode "reportType=adjustments" \
--data-urlencode "startDate=2026-07-01T00:00:00Z" \
--data-urlencode "endDate=2026-07-21T23:59:59Z"Siguientes pasos
- Lotes y Valuación FIFO — la fuente de valuación correcta hoy.
- Ajustes de inventario
- Transferencias entre ubicaciones
- Conteos cíclicos y físicos
- Catálogo de Errores