bruxel.ai

Últimos cambios

Novedades de la API pública.

2026-10-09
videocambio

Video: ai_model_id y extra_ref_ids se retiran

POST /v1/products/{id}/ai-video y su guion ya no aceptan ai_model_id ni extra_ref_ids («la modelo en los cortes»): el proveedor rechaza la cara de la modelo. Mandarlos responde 422 (X-Bruxel-Reason: params) sin reservar créditos. El video por tomas, el que admite a la modelo, por ahora solo existe desde la app.

2026-10-08
reportesbi

Los reportes, también por la API

Con el scope nuevo reports:read tu BI lee los mismos reportes de la sección: GET /v1/reports da el catálogo con cuántas filas trae cada uno en el periodo, GET /v1/reports/:id/rows una página en JSON (hasta las primeras 10,000 filas) y GET /v1/reports/:id.csv el archivo completo. El periodo va con from, to y tz; brand y status filtran donde el reporte los usa.

2026-10-08
flujoswebhooks

Los flujos avisan: te toca, se detuvo, terminó

Tres eventos de webhook nuevos: flow.step.ready (productos que llegaron a un paso), flow.run.blocked (recorridos que se detuvieron con un error) y flow.run.completed (recorridos que terminaron). Llegan agregados, uno por paso o por flujo, con cuántos y una muestra de hasta 20; la lista completa sale de GET /v1/flows/:slug/steps/:key/products y de GET /v1/flows/:slug/runs, con cursor. Activar un flujo despierta una vez por paso con productos.

2026-10-07
flujossistemas

Los pasos de tus sistemas: avisos y llamadas

Un paso de un flujo también se da por hecho cuando Bruxel le entrega un aviso a un sistema (un webhook contestado con un 2xx) o cuando la llave de ese sistema lee o escribe la ficha (consultar su recorrido o su historial no cuenta). En GET /v1/products/:id/journey, `cause` puede valer `delivery` o `api_call`, y `event_system` y `event_type` dicen el sistema y qué fue: el aviso o la operación (`read` o `write`). Un evento sin `system` toma el del sistema conectado al que está ligada la llave.

2026-10-06
flujoseventos

Reporta lo que pasa afuera, y lee el recorrido de un producto

POST /v1/events (scope `events:write`) recibe hasta 100 eventos por llamada: qué sistema, qué pasó, si salió bien y cuándo. Un paso de un flujo puede darse por hecho con ese evento. GET /v1/products/:id/journey (scope `catalog:read`) devuelve dónde va el producto en cada flujo y lo que los sistemas reportaron de él.

2026-09-27
catálogoatributos

Atributos derivados: `derived` y el 422 `derived`

`GET /v1/attributes` trae `derived`: `true` si el valor lo pone el sistema a partir de otro dato (otro atributo, la categoría o la marca) según una regla del cliente. En un producto donde la derivación aplica, `PUT /v1/products/{id}/attributes/{code}` responde 422 con `X-Bruxel-Reason: derived` y no escribe: se cambia el origen y el derivado se recalcula en la misma escritura.

2026-09-25
atributos

Listas compartidas: `value_list` en cada atributo

`GET /v1/attributes` trae `value_list`: el código de la lista compartida de la que vienen las opciones del atributo, o `null`. Las opciones de un atributo ligado se leen y se asignan igual que siempre; lo que cambia es que se editan en la lista, desde la app.

2026-09-25
catálogokits

Kits: la composición de un producto, por SKU

`GET` y `PUT /v1/products/{product_id}/components` (scopes `catalog:read`/`catalog:write`) leen y escriben la composición de un kit: los productos que lo forman, con su cantidad y en orden, más `part_of` (en cuántos kits está el producto). Un SKU desconocido es 422 que lo nombra; un kit tiene un solo nivel. El upsert y el import también arman kits desde `associated_skus` o `kit_components` (`sku=cantidad`), y el canal los emite con la columna `kit.components`.

2026-09-25
catálogoatributoscanales

Un valor propio por canal: `is_channel_scoped` y `channel`

`GET /v1/attributes` dice qué atributos tienen un valor propio por canal (`is_channel_scoped`). En esos, `PUT /v1/products/{id}/attributes/{code}` acepta `channel` (el `slug` del canal) para escribir el valor de ESE canal sin tocar el maestro, y `GET …/attributes?channel=` lo lee con fallback al maestro: el mismo valor que sale en el CSV del canal. Un atributo que no es por canal o un canal que no existe son 422.

2026-09-25
canalesatributos

El valor de cada opción en cada canal: `map` y `strict`

`GET /v1/channels` trae, por columna, `map` (el valor que ESE archivo escribe para cada opción de una lista: «Rojo» → «Red» en Amazon, «001» en el ERP) y `strict` (una opción sin valor para el canal sale vacía y el producto cuenta como incompleto en `readiness`). La llave es el texto que la celda tendría sin el mapeo, en el idioma del canal. Con `null`/`false` la celda sale como siempre.

2026-09-24
catálogocanales

¿Este producto sale completo en el canal? — por producto

`GET /v1/products/{id}/channels/readiness` (scope `channels:read`) dice, por cada canal configurado, si el producto saldría completo en su CSV: `published` (hay ficha publicada en el idioma del canal), `ready` y `missing` con cada columna que falta y su fuente (`output.{campo}`, `attribute.{code}`, `media.*`). Es lo que un middleware mira antes de crear el producto en la tienda. Mismo resolvedor que el archivo; no cobra.

2026-09-24
mediawebhooks

Subir y vincular imágenes por API (media:write)

Nuevo scope `media:write` y cuatro rutas: `POST /v1/media/presign` reserva cuota y devuelve el POST firmado de S3; `POST /v1/media/{asset_id}/complete` confirma por firma binaria y peso real; `POST /v1/products/{id}/media` vincula el asset con su rol y `DELETE /v1/products/{id}/media/{asset_id}` lo desvincula. Es la misma puerta del DAM que usa la app: la caja nunca ve los bytes, la cuota se reserva antes de firmar y un archivo que miente sobre su tipo se descarta.

2026-09-24
catálogoatributosidiomas

Escribir el valor de un atributo en un idioma

`PUT /v1/products/{id}/attributes/{code}` acepta `language`: escribe el valor EN ESE IDIOMA de un atributo localizable; sin él, el valor va al slot global como siempre. `GET /v1/attributes` dice de antemano quién lo acepta (`is_localizable`). Un idioma que no soportamos, o un atributo que no es localizable, es 422 que nombra el código — y `GET …/attributes?language=xx` también es 422 ahora, en vez de un 200 con los valores globales.

2026-09-24
catálogoatributos

Grupos de atributos en GET /v1/attributes

Cada atributo trae `group`: el código del grupo (la sección de la ficha) al que pertenece, o `null`. Es el código y no un id porque esta API habla en códigos: un integrador que arma la fila de un equipo filtra por él sin un segundo viaje. Los grupos se definen en la app o con la columna `group` del CSV de definiciones.

2026-09-24
catálogoatributos

Filtrar el catálogo por el valor de un atributo

`GET /v1/products` acepta `attr=codigo:valor` (repetible, hasta cinco, en AND): el texto de la opción en una lista, Sí/No en un booleano, texto exacto, número o fecha; `codigo:` vacío deja los productos SIN valor. Es la misma pregunta que hace la cola de un equipo en la app —por ejemplo `attr=ready_to_master_data:Sí&attr=ready_to_sap:`— y lo que no se puede aplicar es 422 con la causa, nunca una lista vacía.

2026-09-24
catálogowebhookshistorial

El feed de cambios de ficha, y un `product.updated` que dice qué cambió

`GET /v1/products/deltas` recorre el historial de todas tus fichas con un cursor reanudable: por cada versión dice el producto, el motivo y QUÉ cambió (campos, códigos de atributo, categorías, familia), nunca los valores; con `attribute=` y `reason=` escuchas solo una bandera o un motivo. Y el webhook `product.updated` ahora sale de cualquier cambio real de la ficha —también al escribir el valor de un atributo, que antes no avisaba— con `version`, `reason` y `changed`. Es un despertador: relee la ficha o el feed, no confíes solo en `changed`.

2026-09-23
catálogohistorial

El historial de la ficha registra los cambios del catálogo

El historial de cada ficha ahora registra lo que le pasa cuando cambia el catálogo: borrar un atributo, una opción, una categoría o una familia, o renombrar una opción o un code, deja una versión con `reason` `structure`. Y `changes` puede traer dos claves nuevas: `replaced` (el code ahora es otro atributo) y `recoded` (el mismo atributo con otro code).

2026-09-20
catálogocanales

Unidades de medida en atributos y canales

Un atributo de medida ahora dice de qué medida es y qué unidades acepta: `GET /v1/attributes` trae `dimension` y `accepted_units`, y el `PUT` de un valor admite «1.7 fl oz» en un atributo en ml (se convierte solo). Y cada columna de canal puede pedir otra unidad, otros decimales o el número sin la unidad: `GET /v1/channels` lo expone en `columns[]` para que sepas leer la celda.

2026-09-17
catálogocanales

Productos relacionados por API

Ya puedes leer y escribir con qué otros productos se ofrece cada uno —relacionados, venta cruzada y venta superior— por SKU, y descargarlos en el CSV de tu canal con los nombres de columna que tu tienda espera.

2026-09-12
contenidopublicación

Publicar, aprobar y des-publicar por API

Tres endpoints nuevos con su propio scope `content:manage`: publicar una versión concreta, aprobar el candidato del workflow editorial y dejar de servir una ficha. El scope es aparte de `catalog:write` a propósito — escribir la ficha y decidir qué sirve tu tienda son cosas distintas.

2026-09-12
catálogohistorial

Historial de la ficha: qué cambió en un producto y cuándo

GET /v1/products/{product_id}/revisions devuelve las versiones de una ficha, de la más reciente a la más antigua, con qué cambió en cada una: 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. Para el integrador que sincroniza y quiere saber qué mirar sin volver a descargar la ficha entera.

2026-09-11
canalesexport

Canales: qué columnas son requeridas y cuántos productos están listos

GET /v1/channels ahora trae `columns[].required` y `skip_incomplete` (si el canal omite las filas incompletas de su CSV y su feed). Y GET /v1/channels/{slug}/readiness dice cuántos productos saldrían completos en el canal, cuántos no tienen ficha publicada y qué columnas requeridas faltan más — con el mismo criterio que el archivo.

2026-09-10
imágenes3D

El objeto 3D del producto, en el mismo endpoint de medios

GET /v1/products/{id}/media puede traer un cuarto rol: model_3d. Su url es el GLB y el campo nuevo usdz_url es el mismo modelo en USDZ, lo único que abre Quick Look en iPhone; en una imagen o un video es null. Aditivo: si ya integras, tu contrato no cambia — pero elige la imagen base por role, no por el índice 0.

2026-09-10
atributosexport

El código del atributo en tu tienda

GET /v1/attributes devuelve external_code: el attribute_code con el que Adobe Commerce conoce cada atributo, capturado en Bruxel. Cuando existe, /v1/export/catalog.csv nombra así la columna en vez de con code. null = sin código externo; nada cambia.

2026-09-07
video

Video por API: clips de hasta 30 segundos, con guion

POST /v1/products/{id}/ai-video arranca un clip a partir de una imagen ya guardada del producto: cinco segundos con tarifa plana, o hasta 30 con audio cobrados por segundo × calidad. Con ai_model_id la misma modelo sale en todos los cortes. POST /v1/products/{id}/ai-video/script escribe el guion por tomas con IA (3 créditos, al éxito).

2026-09-07
imágenes

El look de cada foto: peinado, maquillaje y vestuario

POST /v1/products/{id}/ai-media acepta hairstyle, makeup y outfit para dirigir cómo se ve la modelo en ESA foto, sin tocar su identidad. Los tres abren en as_model y con ese valor nada cambia respecto a lo de antes; el job los devuelve en look.

2026-09-04
imágenes

Ropa y expresión en la generación de imágenes

POST /v1/products/{id}/ai-media acepta subject (product | garment) para que la modelo se ponga la prenda en vez de sostenerla, y expression (natural, smile, laugh, neutral, serious, playful) para elegir su cara. Los dos son opcionales y su default reproduce el comportamiento anterior; el job los devuelve en subject y expression.

2026-09-03
imágeneswebhooks

Imágenes: feed de cambios, webhook y generación por API

GET /v1/media/deltas dice qué productos movieron su galería (incluidos los borrados); el evento media.updated avisa en tiempo real; GET /v1/products/{id}/media trae el rol real (aparece swatch), la posición y la procedencia (origin, synthetic_performer); y con el scope nuevo media:generate se abren sesiones de fotos con IA desde tu sistema (POST /v1/products/{id}/ai-media, GET /v1/ai-media/jobs/{id}, GET /v1/ai-models).

2026-07-21
llavesauth

API keys por organización

Nuevas llaves bxk_ con permisos por scope (catalog:read, generate, export…), entrega de un solo uso y revocación inmediata desde la consola.

2026-07-21
generación

Lotes asíncronos con idempotencia

Endpoint POST /v1/batches para timbrar en volumen: reserva de créditos, Idempotency-Key obligatoria y cobro por resultado al leer.

2026-07-13
export

Export de catálogo por idioma

GET /v1/export/catalog.csv?language=es devuelve tu catálogo timbrado en el idioma solicitado, en formato Adobe Commerce.

Changelog — Bruxel