bruxel.ai

Catálogo de productos

Empuja y mantén tu catálogo por SKU desde tu propio sistema (ERP, PIM, tienda).

Endpoints

EndpointQué hace
GET /v1/productsLista paginada (limit ≤ 200, offset, q de búsqueda, status). Scope catalog:read.
GET /v1/products/{id}Detalle de un producto, incluido su source_data. Scope catalog:read.
POST /v1/productsUpsert masivo por SKU, hasta 500 por request. Scope catalog:write.
PATCH /v1/products/{id}Edición parcial de sku, name, brand o category. Scope catalog:write.
DELETE /v1/products/{id}Borrado suave (204). Conserva el historial; se oculta de listas y export. Scope catalog:write.
GET /v1/products/{id}/revisionsQué ha cambiado en la ficha: versiones, con qué cambió en cada una. Scope catalog:read.

Upsert masivo por SKU

El POST es idempotente por (organización, SKU): re-enviar el mismo lote deja el catálogo igual, y un SKU previamente borrado se revive. La respuesta desglosa cuántos se crearon, actualizaron u omitieron.

POST /v1/products
{
  "products": [
    {
      "sku": "CAMISA-001",
      "name": "Camisa de lino",
      "brand": "Acme",
      "category": "Ropa/Camisas",
      "source_data": { "color": "azul", "talla": "M" }
    }
  ]
}

{ "total": 1, "created": 1, "updated": 0, "skipped": 0 }
Un re-upsert REEMPLAZA el producto entero por SKU (incluido su source_data). Manda siempre el producto completo, no solo los campos que cambiaron — para ediciones puntuales usa PATCH.

source_data

source_data es tuyo: un objeto JSON libre con los atributos extra de tu producto (color, talla, material, especificaciones…). El motor de generación lo usa como contexto para escribir mejores descripciones — entre más rico, mejor el resultado.

Editar y borrar

PATCH edita campos sueltos sin tocar el resto. El status del producto NO se edita por API (lo maneja el ciclo de generación). Si el SKU nuevo ya existe en otro producto, responde 409.

DELETE es un borrado suave: el producto desaparece de listas y del export pero su historial se conserva, y un upsert posterior con el mismo SKU lo revive. Repetir el DELETE responde 404.

Historial de una ficha

Si sincronizas con tu tienda, esto te dice qué mirar sin volver a descargar la ficha entera: cada versión trae qué cambió respecto a la anterior — campos, atributos (por código e idioma), categorías y familia. De los datos importados se reportan los nombres de las columnas que cambiaron, nunca su contenido.

GET /v1/products/7f3a…/revisions

{
  "revisions": [
    {
      "version": 7,
      "reason": "import",
      "created_at": "2026-09-12T05:03:11Z",
      "changes": {
        "base": { "name": ["Crema hidratante", "Crema hidratante 50 ml"] },
        "values": { "tamano": { "": [["1.7 OZ"], ["50 ml"]] } },
        "source_data": { "changed": ["precio"] }
      }
    }
  ],
  "total": 7,
  "limit": 20
}

Se pagina hacia atrás: limit (1–50, por defecto 20) y before_version, al que le pasas la versión más baja que recibiste. changes llega vacío en la primera versión de un producto, que no tiene con qué compararse; y si un cambio es enorme, llega recortado con _truncated y conteos.

No trae quién hizo el cambio —es dato interno de tu organización, y sale en la app— ni el estado completo de la ficha en cada versión, que se pide con el detalle del producto. Volver a una versión anterior tampoco se puede por API: se hace desde la app, donde requiere rol de administrador.
Catálogo de productos — Bruxel