C
Cotizera Docs

Productos

API de Productos

Endpoints para administrar tu catálogo de productos, incluyendo marcas y categorías para su organización.


Listar Productos

GET /api/products

Permiso: products:read

Obtén una lista paginada de productos activos del tenant actual.

Query Parameters:

Parameter Type Required Description
search string No Busca por nombre de producto o modelo/SKU (sin distinguir mayúsculas)
brandId string No Filtra por ID de marca
categoryId string No Filtra por ID de categoría
page number No Número de página (por defecto: 1)

Response 200 OK:

{
  "data": [
    {
      "id": "clxyz...",
      "name": "Laptop HP ProBook 450",
      "description": "Laptop empresarial con procesador i7",
      "modelSku": "PB450-G10",
      "price": "18500.00",
      "isActive": true,
      "brand": { "id": "...", "name": "HP" },
      "category": { "id": "...", "name": "Laptops" },
      "createdAt": "2026-03-01T10:00:00.000Z"
    }
  ],
  "total": 120,
  "page": 1,
  "totalPages": 6
}

Ejemplo con cURL:

curl -X GET "https://cotizera.com/api/products?search=laptop&brandId=clxyz&page=1" \
  -H "Cookie: next-auth.session-token=YOUR_TOKEN"

Crear Producto

POST /api/products

Permiso: products:create

Crea un nuevo producto. Si se proporciona modelSku, debe ser único dentro del tenant.

Request Body:

{
  "name": "Monitor Dell UltraSharp 27\"",
  "description": "Monitor 4K IPS con USB-C",
  "modelSku": "U2723QE",
  "price": 12500,
  "brandId": "clxyz...",
  "categoryId": "clxyz..."
}
Field Type Required Description
name string Yes Nombre del producto (mínimo 1 carácter)
description string No Descripción del producto
modelSku string No Número de modelo o SKU (único por tenant si se proporciona)
price number Yes Precio unitario (> 0)
brandId string No ID de la marca
categoryId string No ID de la categoría

Response 201 Created: Devuelve el producto creado con marca y categoría incluidas.

Errores:

Status Error Cuándo
400 Mensaje de validación Zod Entrada inválida
403 "Sin permisos" El rol no tiene products:create
409 "Ya existe un producto con ese modelo/SKU" SKU duplicado en el tenant

Efectos secundarios:

  • Dispara el evento webhook product.created
  • Activa el paso de onboarding first_product
  • Registra una entrada de auditoría con acción create

Obtener un Producto

GET /api/products/:id

Permiso: products:read

Obtén un producto activo individual con los detalles de marca y categoría.

Response 200 OK: Devuelve el objeto del producto con brand y category incluidos.

Errores:

Status Error Cuándo
404 "Producto no encontrado" Producto no encontrado, inactivo o de otro tenant

Actualizar Producto

PUT /api/products/:id

Permiso: products:update

Actualiza un producto existente. Si se cambia el modelSku, se vuelve a validar la unicidad.

Request Body: Mismo esquema que Crear Producto.

Response 200 OK: Devuelve el producto actualizado con marca y categoría.

Errores:

Status Error Cuándo
404 "Producto no encontrado" Producto no encontrado o inactivo
409 "Ya existe un producto con ese modelo/SKU" El nuevo SKU entra en conflicto con un producto existente

Eliminar Producto (Soft Delete)

DELETE /api/products/:id

Permiso: products:delete

Elimina un producto de forma lógica estableciendo isActive en false.

Response 200 OK:

{
  "success": true
}

Marcas

GET /api/brands

Lista todas las marcas activas del tenant actual, ordenadas alfabéticamente.

Response 200 OK:

[
  { "id": "clxyz...", "name": "HP", "tenantId": "...", "isActive": true },
  { "id": "clxyz...", "name": "Dell", "tenantId": "...", "isActive": true }
]

POST /api/brands

Crea una nueva marca. El nombre debe ser único dentro del tenant.

Request Body:

{
  "name": "Lenovo"
}
Field Type Required Description
name string Yes Nombre de la marca (mínimo 1 carácter)

Response 201 Created: Devuelve la marca creada.

Errores:

Status Error Cuándo
409 "Ya existe una marca con ese nombre" Nombre de marca duplicado en el tenant

Categorías

GET /api/categories

Lista todas las categorías activas del tenant actual, ordenadas alfabéticamente.

Response 200 OK:

[
  { "id": "clxyz...", "name": "Laptops", "tenantId": "...", "isActive": true },
  { "id": "clxyz...", "name": "Monitores", "tenantId": "...", "isActive": true }
]

POST /api/categories

Crea una nueva categoría. El nombre debe ser único dentro del tenant.

Request Body:

{
  "name": "Impresoras"
}
Field Type Required Description
name string Yes Nombre de la categoría (mínimo 1 carácter)

Response 201 Created: Devuelve la categoría creada.

Errores:

Status Error Cuándo
409 "Ya existe una categoria con ese nombre" Nombre de categoría duplicado en el tenant
© 2026 Cotizera. All rights reserved.