Agendar demo
Productos
Catálogo API v1

Productos

Cada item de /catalog/products es un SKU: la unidad que se stockea y se costea de forma independiente.

  • Un producto sin variaciones es un solo SKU.
  • Un producto con variaciones (talla, color…) es un conjunto de SKUs que comparten un Producto (modelo); cada SKU apunta a él con product_id. El modelo se gestiona en Grupos.

Campos

CampoTipoReq.Notas
idnumberIdentificador del SKU (solo en la respuesta)
skustringreqCódigo único por tenant
namestringreq
product_typeenumreqraw_material · finished_good · wip · consumable · service
base_unit_idnumberreqUnidad de stock
category_idnumber
brand_idnumber
product_idnumberProducto (modelo) padre, si es una variante. Vacío = producto simple
descriptionstring
standard_costnumberCosto de referencia
barcodestring
image_urlstring
track_lotsbooleanManejo por lotes (default false)
min_stocknumberMínimo para alertas de reposición
purchase_unit_idnumberUnidad de compra
purchase_to_base_factornumberRequerido si hay purchase_unit_id
is_activebooleanDefault true

Los id son enteros, únicos por tenant. Los campos que gestiona el sistema (id, fechas) no se envían en el body: van solo en la respuesta.

product_type no cambia una vez que el SKU tiene movimientos de stock.

Endpoints

MétodoRutaDescripción
GET/catalog/productsLista de SKUs (con filtros)
GET/catalog/products/{id}Un SKU
POST/catalog/productsCrea un SKU
PATCH/catalog/products/{id}Edita campos (no sku ni product_type)
DELETE/catalog/products/{id}Desactiva (is_active=false, soft delete)

Filtros de GET /catalog/products (query): category_id, brand_id, product_id (las variantes de un Producto), product_type, is_active, search (sku/nombre), limit (≤1000), offset.

Crear un SKU

POST /catalog/products

Request

{
  "sku": "ACE-OLI-500",
  "name": "Aceite de Oliva Extra Virgen 500ml",
  "product_type": "finished_good",
  "base_unit_id": 3,
  "category_id": 18,
  "brand_id": 7,
  "standard_cost": 5000,
  "barcode": "7701234567890"
}

Response 201

{
  "id": 142,
  "sku": "ACE-OLI-500",
  "name": "Aceite de Oliva Extra Virgen 500ml",
  "product_type": "finished_good",
  "base_unit_id": 3,
  "category_id": 18,
  "brand_id": 7,
  "product_id": null,
  "description": null,
  "standard_cost": 5000,
  "barcode": "7701234567890",
  "image_url": null,
  "track_lots": false,
  "min_stock": null,
  "purchase_unit_id": null,
  "purchase_to_base_factor": null,
  "is_active": true
}

Para crear una variante, envía product_id con el Producto (modelo) al que pertenece:

{ "sku": "CAM-AZ-S", "name": "Camiseta Azul S", "product_type": "finished_good", "base_unit_id": 1, "product_id": 30 }

Listar las variantes de un Producto

GET /catalog/products?product_id=30

Devuelve todos los SKUs cuyo product_id es 30.

Editar

PATCH /catalog/products/{id}

Request

{ "standard_cost": 5200, "min_stock": 12 }

Actualiza cualquier campo editable. sku y product_type son inmutables.

Errores

Formato: { "error": "<código>", "message": "<texto>" }

HTTPerrorCuándo
400bad_requestBody inválido o un id referenciado no existe
401unauthorizedCabeceras Emdimo-Api-Key/-Token ausentes o inválidas
403forbiddenLa key no tiene el scope requerido
404not_foundSKU de otro tenant o inexistente
409conflictSKU duplicado
{ "error": "conflict", "message": "El SKU 'ACE-OLI-500' ya existe." }