Catálogo e inventario por API
Los endpoints para leer y escribir el stock, los proveedores, las bodegas, los conteos y los traslados, y para leer el semáforo y el trabajo del día.
En esta página
Todas estas rutas están bajo /inventory. Las lecturas funcionan con una llave de lectura; las escrituras necesitan una de escritura. Si la llave está limitada a algunas bodegas, solo ve y toca esas bodegas.
Stock por SKU
| Método y ruta | Qué hace | Llave |
|---|---|---|
GET /inventory/stock/page | Lista paginada del stock. Parámetros: limit, offset, q (búsqueda), warehouse. | lectura |
GET /inventory/stock | Todo el stock de una vez (sin paginar). | lectura |
GET /inventory/stock/lookup | Busca registros de stock. | lectura |
GET /inventory/stock/{sku} | Un registro. | lectura |
GET /inventory/stock/{sku}/history | La historia del stock de un SKU. | lectura |
PUT /inventory/stock/{sku} | Crea o reemplaza el registro. current_stock es obligatorio. | escritura |
PATCH /inventory/stock/{sku} | Cambia algunos campos de un registro que ya existe. Nunca crea uno. | escritura |
DELETE /inventory/stock/{sku} | Borra el registro de stock. | escritura |
PATCH /inventory/stock/{sku}/product-type | Cambia el tipo de producto (terminado, componente…). | escritura |
GET / PUT / DELETE /inventory/stock/{sku}/suppliers[/{supplier_id}] | Los proveedores vinculados a un SKU. | lectura / escritura |
curl "https://app.stockai.es/api/v1/inventory/stock/page?limit=50&offset=0&warehouse=principal&q=SKU-0" \
-H "Authorization: Bearer $STOCKAI_KEY"# Create or replace a SKU's record (current_stock is required)
curl -X PUT https://app.stockai.es/api/v1/inventory/stock/SKU-001 \
-H "Authorization: Bearer $STOCKAI_KEY" -H "Content-Type: application/json" \
-d '{"current_stock":120,"min_stock":20,"lead_time_days":7,"unit_cost":2.5,
"moq":12,"supplier":"Distribuidora Andina","warehouse":"principal"}'
# Change one field of a record that already exists (never creates one)
curl -X PATCH https://app.stockai.es/api/v1/inventory/stock/SKU-001 \
-H "Authorization: Bearer $STOCKAI_KEY" -H "Content-Type: application/json" \
-d '{"current_stock":118}'Campos que acepta PUT/PATCH: display_name, current_stock, min_stock, lead_time_days, unit_cost, moq, supplier, notes, sale_price, category, family, brand, unit_of_measure, barcode, warehouse. La respuesta es el registro completo:
{
"sku": "SKU-001", "display_name": "SKU-001", "warehouse": "principal",
"current_stock": 120.0, "min_stock": 0.0, "lead_time_days": 7,
"unit_cost": 2.5, "moq": 12.0, "supplier": "Distribuidora Andina",
"product_type": "finished_good", "service_level": 0.95,
"lead_time_set_by": "user", "unit_cost_set_by": "user", "moq_set_by": "user",
"updated_at": "2026-10-01T08:00:00+00:00"
}Los campos *_set_by dicen quién fijó cada valor (user, file, supplier_rule…). Lo que escribes por la API cuenta como dato tuyo.
Importar el stock desde un archivo
# 1. Preview: what was detected and what would be written. Writes nothing.
curl -X POST https://app.stockai.es/api/v1/inventory/bulk/preview \
-H "Authorization: Bearer $STOCKAI_KEY" -F "file=@stock.csv"
# 2. Import. Optional fields: mapping (JSON text), warehouse, thousands_dot, only_fill_missing
curl -X POST https://app.stockai.es/api/v1/inventory/bulk \
-H "Authorization: Bearer $STOCKAI_KEY" -F "file=@stock.csv" -F "warehouse=principal"/inventory/bulk/preview no toca ninguna fila: te dice qué columnas detectó (detected_mapping), qué columnas no usó y qué escribiría. Si un perfil de sincronización es dueño de alguno de esos campos, lo avisa en synced_overwrites. GET /inventory/template.csv descarga la plantilla con los encabezados que se reconocen.
El semáforo y el trabajo del día
GET /inventory/status- El semáforo por SKU: señal, cobertura, punto de reorden y cantidad recomendada. Parámetros opcionales:
session_id(sin él, la sesión activa),signal,supplier,abc,by_warehouse,q,skus,without_forecast,service_level,sort,order,limit,offset. GET /inventory/morning-briefing- El trabajo del día: riesgos, recomendaciones con su motivo, cambios de demanda e indicadores. Parámetros:
session_id,service_level. GET /inventory/dashboard-summary- Los números del panel.
GET /inventory/optimize- Compras y traslados sugeridos por el optimizador, por SKU y bodega (
session_id,horizon_days). GET /inventory/setup-gaps- SKUs a los que les falta configuración (costo, tiempo de entrega…).
GET /inventory/dead-capital,/margin-erosion,/supplier-cost-inflation,/forecast-money- Capital inmovilizado, margen que se erosiona, inflación de costos y proyección de ingresos, costo y margen.
curl "https://app.stockai.es/api/v1/inventory/status?signal=PEDIR_YA&supplier=Andina" \
-H "Authorization: Bearer $STOCKAI_KEY"{
"period": "daily", "coverage_unit": "day",
"items": [{
"sku": "SKU-002", "signal": "PEDIR_YA",
"current_stock": 42.0, "reorder_point": 5919.28, "recommended_qty": 5878.0,
"coverage_days": 0.1,
"lead_time_days": 7, "lead_time_source": "user",
"unit_cost": 5.2, "unit_cost_source": "user",
"moq": 25.0, "moq_source": "user",
"supplier": "Granos del Valle",
"explanation_code": "inventory_explain_reorder",
"explanation_params": { "signal": "PEDIR_YA", "daily_demand": 757.97, "coverage_days": 0.1,
"current_stock": 42.0, "reorder_point": 5919.28,
"lead_time_days": 7, "lead_time_source": "user" },
...
}]
}signal | Significado |
|---|---|
PEDIR_YA | Pide ya: el stock no cubre el tiempo de entrega. |
PEDIR_PRONTO | Pide pronto. |
OK | Cubierto. |
SOBRESTOCK | Hay más de lo necesario. |
SIN_DATOS | No hay stock registrado: no sabemos, que no es lo mismo que «está bien». |
Los campos lead_time_source, unit_cost_source y moq_source dicen de dónde salió cada supuesto: user (lo escribiste), file (vino en tu archivo), supplier_rule (una regla de proveedor), learned (aprendido de tus recepciones; solo en tiempo de entrega) o default (StockAI lo supuso). Maneja los cinco. El porqué de cada recomendación viene estructurado en explanation_code + explanation_params: decide por eso, no por el texto explanation.
Proveedores
| Método y ruta | Qué hace |
|---|---|
GET /inventory/suppliers, GET /inventory/suppliers/page | Lista (completa, o paginada con limit, offset, q). |
POST /inventory/suppliers | Crea un proveedor. Solo name es obligatorio. |
PATCH /inventory/suppliers/{id} | Cambia sus datos. |
DELETE /inventory/suppliers/{id} / POST .../{id}/reactivate | Lo desactiva / lo reactiva (no se borra). |
POST /inventory/suppliers/import/preview, POST /inventory/suppliers/import | Importar desde un archivo (plantilla en GET /inventory/suppliers/import/template). |
GET /inventory/suppliers/scorecard, /lead-time-alerts, /contact-health | Cumplimiento, proveedores que tardan más de lo habitual y datos de contacto que faltan. |
POST /inventory/suppliers/{id}/price-breaks, GET /inventory/price-breaks | Descuentos por volumen. |
curl -X POST https://app.stockai.es/api/v1/inventory/suppliers \
-H "Authorization: Bearer $STOCKAI_KEY" -H "Content-Type: application/json" \
-d '{"name":"Distribuidora Andina","email":"ventas@andina.example",
"lead_time_days":7,"payment_terms":"30 dias","payment_terms_days":30,
"erp_code":"PRV-0042"}'Campos: name, email, phone, whatsapp, lead_time_days, lead_time_std, review_period_days, payment_terms, payment_terms_days, notes y erp_code. El erp_code es el código del proveedor en tu ERP: es lo que el feed de órdenes usa para emparejar documentos.
Bodegas
GET /inventory/warehouseslista las bodegas (id,name,is_default…).POSTcrea una yPATCH /inventory/warehouses/{name}la cambia. El número de bodegas tiene un tope por plan.GET/PUT/DELETE /inventory/warehouses/lanes: las rutas de traslado entre bodegas.
Conteos físicos
# Open a count for one warehouse
curl -X POST https://app.stockai.es/api/v1/inventory/stock-counts \
-H "Authorization: Bearer $STOCKAI_KEY" -H "Content-Type: application/json" \
-d '{"warehouse":"principal","notes":"Monthly count"}'
# Record what was counted, line by line
curl -X PUT https://app.stockai.es/api/v1/inventory/stock-counts/$COUNT_ID/lines \
-H "Authorization: Bearer $STOCKAI_KEY" -H "Content-Type: application/json" \
-d '{"sku":"SKU-001","quantity":117,"mode":"set"}'
# mode "add" (default) accumulates, e.g. one scan = one unit; "set" replaces the counted total.
# client_ref (optional): an id per scan, so a retried request is ignored.
# See the differences, then apply them to the stock
curl https://app.stockai.es/api/v1/inventory/stock-counts/$COUNT_ID/preview -H "Authorization: Bearer $STOCKAI_KEY"
curl -X POST https://app.stockai.es/api/v1/inventory/stock-counts/$COUNT_ID/apply -H "Authorization: Bearer $STOCKAI_KEY"Un conteo se abre (POST), se llenan sus líneas (PUT .../lines, DELETE .../lines/{sku}), se revisa (GET .../preview) y se aplica (POST .../apply) o se cierra / cancela (.../close, .../cancel). Aplicar ajusta el stock a lo contado.
Traslados entre bodegas
curl -X POST https://app.stockai.es/api/v1/inventory/transfers \
-H "Authorization: Bearer $STOCKAI_KEY" -H "Content-Type: application/json" \
-d '{"from_warehouse":"principal","to_warehouse":"norte",
"items":[{"sku":"SKU-001","qty":10}],"notes":"Weekly rebalancing"}'Después: POST /inventory/transfers/{id}/receive cuando llega, .../close para cerrarlo y .../cancel para anularlo. GET /inventory/transfers los lista.
Otros recursos del inventario
- Eventos de demanda
/inventory/eventsy su catálogo: temporadas y fechas que mueven la demanda, con sus multiplicadores.- Listas de materiales
/inventory/bom/{parent_sku}: componentes de un producto armado;GET /inventory/production-requirementsexplota la demanda en componentes.- Mermas
GET/POST /inventory/shrinkagey sus motivos.- Dinero
/inventory/cash-calendar,/inventory/roi,/inventory/roi/monthly.- Informe
GET /inventory/report/pdfdescarga el informe de inventario en PDF.