Guía completa: catalogar un producto de principio a fin

Esta guía recorre el flujo recomendado para catalogar un producto en el Marketplace: desde la creación del producto, su categorización, atributos (opciones y combinaciones), precios, stock, imágenes y precios específicos (descuentos). Incluye un diagrama del flujo y ejemplos con cURL.

Requisitos previos: token de API (ver Autenticación) y dominio de tu marketplace (ver Entornos y dominios).


Para integradores: orden recomendado en una migración

Al mudar un catálogo desde otro sistema, conviene seguir este orden para minimizar rechazos del API y reutilizar IDs:

Orden Paso Motivo
1 Consultar categorías y carriers Mapear IDs de origen → IDs del marketplace
2 Crear producto (active: 0) Obtener id_product para todo lo demás
3 Asignar categorías (en el POST o PUT) Requerido para categorización correcta
4 Subir al menos una imagen En muchos marketplaces es obligatorio para activar
5 Asignar transportistas (id_carriers) Requerido en algunos marketplaces para activar
6 Activar producto (PUT con active: 1) Hacerlo después de imágenes y carriers si aplica
7 Opciones/valores y combinaciones Solo si el producto tiene variantes
8 Stock por producto/combinación Siempre
9 Precios específicos (descuentos) Opcional
10 Características (product_features) Opcional, para fichas técnicas

Checklist por producto: referencia/SKU único → categorías mapeadas → nombre/descripción → precio → imagen(es) → carriers (si aplica) → activar → variantes+stock si aplica → descuentos si aplica.


Diagrama del flujo de catalogación

El siguiente diagrama muestra el orden recomendado y las dependencias entre recursos. Las flechas indican “usa el ID devuelto en el paso anterior”.

flowchart TB subgraph prep ["Preparación opcional"] A["Consultar categorías - GET categories"] B["Crear opciones - POST product_options"] C["Crear valores opción - POST product_option_values"] D["Crear características - POST product_features"] E["Crear valores características - POST product_feature_values"] end subgraph producto ["Producto base"] F["Crear producto - POST products"] F2["Activar producto - PUT products"] end subgraph variaciones ["Variaciones y stock"] G["Crear combinaciones - POST combinations"] H["Gestionar stock - PUT POST stock_availables"] end subgraph contenido ["Contenido y precios"] I["Subir imágenes - POST images products"] J["Precios específicos - POST specific_prices"] end A --> F F --> I I --> F2 F --> F2 F2 --> G B --> C C --> G D --> E G --> H F --> J

Resumen del flujo:

Paso Acción Cuándo
1 Consultar categorías Para elegir id_category_default y categorías asociadas
2 Crear producto Siempre (nombre, referencia, precio, categorías); en muchos entornos con active: "0"
2c Asignar transportistas Si el API lo exige: GET /api/carriers y PUT producto con id_carriers; si no, backoffice
3 Imágenes Subir al menos una; en muchos marketplaces obligatorio para poder activar
4 Activar producto Después de imágenes y carriers: PUT con active: "1" (puede exigir más campos)
5 Opciones y valores Solo si el producto tiene variantes (talla, color, etc.)
6 Combinaciones Solo si hay variantes; vinculan producto + valores de opción
7 Stock Siempre (producto simple o por combinación)
8 Precios específicos Opcional; descuentos por fecha, cantidad, etc.
9 Características (product_features) Opcional; especificaciones técnicas o descriptivas

Formato de los cURLs y variables

En los ejemplos se usa:

  • URL: https://{{domain}}/api/...{{domain}} es el host del marketplace (ej. tiendagalicia-uat.aper.cloud).
  • Headers: Content-Type: application/json y Authorization: Basic {{token_encode}}, donde {{token_encode}} es el token con : al final codificado en Base64.

Variables usadas en los ejemplos:

Variable Descripción
{{domain}} Dominio del API (sin https://)
{{token_encode}} Token codificado en Base64 (token + : → Base64)
{{product_id}} / {{id_product}} ID del producto
{{id_combination}} ID de la combinación
{{id_stock_available}} ID del registro de stock
{{id_image}} ID de la imagen
{{id_specific_price}} ID del precio específico
{{id_feature}} ID de la característica (product_feature)
{{id_attribute_group}} ID del grupo de opción (product_options)

Para usar los cURLs en terminal, define las variables y sustituye {{domain}} y {{token_encode}} en cada comando:

export domain="tiendagalicia-uat.aper.cloud"
export token_encode="TU_TOKEN_EN_BASE64"
# En los cURLs reemplaza {{domain}} por $domain y {{token_encode}} por $token_encode

Notas aprendidas en integración

Estas notas provienen de pruebas end-to-end en entornos UAT (p. ej. ICBC Mall UAT). Conviene tenerlas en cuenta al integrar.

  • Alta de producto y active: En algunos marketplaces no se puede activar el producto en el alta. El API devuelve error tipo "No puede activar un producto durante el alta por medio de la propiedad 'active'". En ese caso, envía siempre "active": "0" en el POST /api/products y activa el producto después con un PUT /api/products/{id} cuando corresponda.

  • Opciones de producto (product_options): En algunos entornos el formato con "id" y "value" dentro de name.language / public_name.language devuelve error de validación ("Property AttributeGroup->name is empty"). Usa el formato con "@id" y "%" (ej. "language": [{"@id": "1", "%": "Talla"}]) para que la petición sea aceptada.

  • Transportistas (carriers): Para asignar transportistas al producto hace falta conocer sus IDs. Si la clave de API tiene permiso de lectura sobre el recurso carriers, obtén los IDs con GET /api/carriers (formato en el producto: lista separada por comas, ej. "91,378"). Si no tienes acceso vía API a carriers, puedes consultar los IDs en el backoffice del marketplace (sección de envíos o transportistas) y usarlos igualmente en id_carriers. Tras asignar carriers válidos, la activación puede pasar a exigir otro requisito (p. ej. imágenes).

  • Activación e imágenes: En algunos marketplaces no se puede activar un producto sin al menos una imagen. El API devuelve "No se puede activar un producto sin imágenes". Sube al menos una imagen con POST /api/images/products/{id_product} antes de hacer el PUT con active: "1".

  • PUT de activación: En entornos estrictos, el PUT que activa el producto puede exigir más campos que solo id y active (p. ej. name, installments_fixed, id_shop_default, price). Si recibes errores tipo "parameter X required" o "mantenga esta propiedad como se encuentra", reenvía el cuerpo con los campos obligatorios del producto además de active: "1".


Mapeo desde tu catálogo origen

Al migrar desde otro sistema (ERP, ecommerce, CSV), ten en cuenta:

Origen típico En esta API Nota
SKU / Código artículo reference Debe ser único por producto
Nombre / Título name.language[].% Formato [{"@id": "1", "%": "Texto"}]
Descripción larga description Mismo formato multiidioma
Precio (numérico) price Decimal, hasta 2 decimales
Categorías (IDs o nombres) id_category_default + associations.categories Hay que resolver nombres → IDs con GET /api/categories
Variantes (talla, color) product_options + product_option_values + combinations Crear grupo, valores, luego combinaciones por producto
Stock por ítem/variante stock_availables (PUT cantidad) id_product_attribute: 0 = producto base; si no, id de combinación
Imagen principal + adicionales POST /api/images/products/{id} Al menos una imagen antes de activar en muchos entornos
Descuentos / promos specific_prices reduction_type: percentage o amount; from/to para vigencia

Idioma: El @id en language es el ID de idioma del marketplace (suele ser 1). Si tu catálogo es multiidioma, repite el bloque por cada idioma o consulta GET /api/languages si está disponible.


1. Consultar categorías disponibles

Antes de crear el producto necesitas el ID de categoría por defecto (id_category_default, en el portal suele ser 2) y, si aplica, los IDs de categorías adicionales para associations.categories.

cURL de ejemplo:

curl -X GET "https://{{domain}}/api/categories?display=full" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}"

Guarda los id que quieras usar en el siguiente paso.


2. Crear el producto

Creación mínima: nombre, referencia (SKU), precio, categoría por defecto y categorías asociadas.

Campos clave:

  • id_category_default: normalmente "2".
  • reference: identificador único (ej. SKU).
  • price: precio con hasta dos decimales.
  • name / description: formato multiidioma con language, @id y %.
  • active: en el alta debe ser "0" en muchos entornos; no se permite activar durante el alta. Para publicar el producto, actívalo después con PUT /api/products/{id} poniendo "active": "1".

cURL de ejemplo:

curl -X POST "https://{{domain}}/api/products" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "product": {
        "id_manufacturer": "0",
        "id_category_default": "2",
        "id_shop_default": "1",
        "new": "",
        "cache_default_attribute": "0",
        "id_tax_rules_group": "2",
        "type": "simple",
        "reference": "MP-000002",
        "width": "0",
        "height": "0",
        "depth": "0",
        "weight": "0",
        "minimal_quantity": "1",
        "price": 1159,
        "wholesale_price": "0",
        "unit_price_ratio": "0",
        "active": "0",
        "redirect_type": "404",
        "id_product_redirected": "0",
        "available_for_order": "1",
        "condition": "new",
        "show_price": "1",
        "indexed": "1",
        "date_add": "2019-08-08 12:25:40",
        "link_rewrite": {
            "language": {
                "@id": "1",
                "%": "product-link-rewrite"
            }
        },
        "name": {
            "language": {
                "@id": "1",
                "%": "Andador 2 en 1 Maxi Top PTAND3250 Rondi"
            }
        },
        "description": {
            "language": {
                "@id": "1",
                "%": "description"
            }
        },
        "description_short": {
            "language": {
                "@id": "1",
                "%": "short description"
            }
        },
        "available_now": {
            "language": {
                "@id": "1",
                "%": "1"
            }
        },
        "associations": {
            "categories": [
                { "id": "2" },
                { "id": "1105" }
            ]
        }
    }
  }'

Para asignar categorías al crear, incluye el bloque associations.categories (como arriba). De la respuesta, anota el id del producto (usar como {{id_product}} o {{product_id}} en los siguientes pasos).


2b. Activar el producto

En los entornos donde el alta exige "active": "0", hay que activar el producto después con un PUT para que sea visible en el catálogo.

cURL de ejemplo:

curl -X PUT "https://{{domain}}/api/products/{{product_id}}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "product": {
        "id": "{{product_id}}",
        "active": "1"
    }
  }'

Notas: En algunos marketplaces el API puede devolver "No se puede activar un producto sin transportistas" → asigna antes transportistas (paso 2c). También puede devolver "No se puede activar un producto sin imágenes" → sube al menos una imagen (sección 7) antes de activar.

Si el API exige más campos en el PUT (p. ej. "parameter X required", "id_shop_default", "installments_fixed"), envía un cuerpo completo con los datos actuales del producto más active: "1" (y id_carriers si ya los asignaste). Ejemplo mínimo que suele aceptarse:

curl -X PUT "https://{{domain}}/api/products/{{product_id}}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "product": {
        "id": "{{product_id}}",
        "id_shop_default": "1",
        "id_carriers": "91,378",
        "id_manufacturer": "0",
        "id_category_default": "2",
        "reference": "MP-000002",
        "price": 12499.99,
        "minimal_quantity": "1",
        "installments_fixed": "3",
        "name": {"language": [{"@id": "1", "%": "Nombre del producto"}]},
        "description": {"language": [{"@id": "1", "%": "Descripción"}]},
        "description_short": {"language": [{"@id": "1", "%": "Resumen"}]},
        "link_rewrite": {"language": [{"@id": "1", "%": "slug-producto"}]},
        "active": "1"
    }
  }'

Sustituye id_carriers por los IDs reales de GET /api/carriers y el resto por los valores del producto.


2c. Asignar transportistas al producto (si aplica)

Cuando el marketplace exige que el producto tenga transportistas para poder activarse, puedes intentar asignarlos con un PUT del producto incluyendo el campo id_carriers.

1. Obtener IDs de transportistas disponibles

Si tu clave de API tiene permiso sobre el recurso carriers, puedes listarlos con:

curl -X GET "https://{{domain}}/api/carriers?display=full" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}"

Anota los id de los carriers que quieras asociar al producto.

Si no tienes acceso vía API (por ejemplo, el recurso carriers no está habilitado para tu clave), también puedes consultar los IDs de transportistas en el backoffice del marketplace, en la sección de envíos o transportistas, y usar esos IDs en el campo id_carriers del producto.

2. Actualizar el producto con transportistas

En esta API no está documentado un endpoint específico tipo PUT /api/carriers/{id} para editar transportistas. La relación producto–transportista se gestiona a nivel de producto: el recurso producto incluye el campo id_carriers. Puedes intentar actualizar el producto enviando ese campo en un PUT:

curl -X PUT "https://{{domain}}/api/products/{{product_id}}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "product": {
        "id": "{{product_id}}",
        "id_carriers": "1,2",
        "active": "1"
    }
  }'

Sustituye "1,2" por los IDs de transportistas devueltos en el paso 1 (formato lista separada por comas, ej. "91,378"). La clave de API debe tener permiso de lectura sobre el recurso carriers para poder llamar a GET /api/carriers.

Si el API no acepta id_carriers en el PUT o sigue devolviendo que no se puede activar sin transportistas, la asignación debe hacerse desde el backoffice del marketplace o con soporte técnico.


3. Categorización al actualizar

Para añadir o quitar categorías en un producto ya creado, usa PUT con la lista completa de categorías. Las que no envíes se desvinculan.

cURL de ejemplo:

curl -X PUT "https://{{domain}}/api/products/{{product_id}}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "product": {
        "id": "{{product_id}}",
        "id_manufacturer": "0",
        "id_category_default": "2",
        "new": null,
        "cache_default_attribute": "0",
        "id_tax_rules_group": "3",
        "position_in_category": "1",
        "type": "simple",
        "id_shop_default": "1",
        "reference": "MP-000002",
        "width": "0.000000",
        "height": "0.000000",
        "depth": "0.000000",
        "weight": "0.000000",
        "minimal_quantity": "1",
        "price": 1159.000000,
        "wholesale_price": "0.000000",
        "unit_price_ratio": "0.000000",
        "active": "0",
        "redirect_type": "",
        "id_product_redirected": "0",
        "available_for_order": "1",
        "condition": "new",
        "show_price": "1",
        "indexed": "0",
        "date_add": "2020-06-01 14:58:42",
        "link_rewrite": {
            "language": [
                { "@id": "1", "%": "product-link-rewrite" }
            ]
        },
        "name": {
            "language": [
                { "@id": "1", "%": "Andador 2 en 1 Maxi Top PTAND3250 Rondi" }
            ]
        },
        "description": {
            "language": [
                { "@id": "1", "%": "description" }
            ]
        },
        "description_short": {
            "language": [
                { "@id": "1", "%": "short description" }
            ]
        },
        "available_now": {
            "language": [
                { "@id": "1", "%": "" }
            ]
        },
        "associations": {
            "categories": [
                { "id": "2" },
                { "id": "1105" },
                { "id": "1106" }
            ]
        }
    }
  }'

4. Atributos: opciones y valores (variantes)

Si el producto tiene variantes (talla, color, etc.):

  1. Crear el grupo de opción (product_options), por ejemplo “Color” o “Talla”.
  2. Crear los valores (product_option_values) para ese grupo.
  3. Usar esos valores al crear combinaciones (paso 5).

4.1 Crear opción de producto (grupo)

En integración se ha comprobado que el formato con "@id" y "%" en name y public_name es el que aceptan todos los entornos; el uso de "id"/"value" puede devolver error de validación.

cURL de ejemplo:

curl -X POST "https://{{domain}}/api/product_options" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "product_options": {
        "is_color_group": "0",
        "group_type": "select",
        "position": "0",
        "name": {
            "language": [
                { "@id": "1", "%": "Talla" }
            ]
        },
        "public_name": {
            "language": [
                { "@id": "1", "%": "Talla" }
            ]
        }
    }
  }'

Anota el id del grupo creado (será el id_attribute_group al crear valores).

4.2 Crear valor de opción

Sustituye id_attribute_group por el ID del grupo del paso anterior (ej. 4).

cURL de ejemplo:

curl -X POST "https://{{domain}}/api/product_option_values" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "product_option_values": {
        "id_attribute_group": "4",
        "name": {
            "language": {
                "@id": "1",
                "%": "Azul"
            }
        }
    }
  }'

Repite para cada valor (Azul, Verde, etc.) y anota los id para las combinaciones.


5. Combinaciones (producto con variantes)

Cada combinación une un producto con uno o más valores de opción y puede tener impacto en precio y stock propio. Usa {{id_product}} y el id del valor de opción devuelto en el paso 4.2.

cURL de ejemplo:

curl -X POST "https://{{domain}}/api/combinations" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "combination": {
        "id_product": "10",
        "location": "",
        "ean13": "",
        "upc": "",
        "quantity": "25",
        "reference": "VTEX-ABC-80-5024",
        "supplier_reference": "",
        "wholesale_price": "0.000000",
        "price": "48",
        "ecotax": "0.000000",
        "weight": "0.000000",
        "unit_price_impact": "0.000000",
        "minimal_quantity": "1",
        "default_on": "0",
        "available_date": "0000-00-00",
        "associations": {
            "product_option_values": {
                "product_option_values": [
                    { "id": 9 }
                ]
            }
        }
    }
  }'

Sustituye id_product por tu {{id_product}} y el id dentro de product_option_values por el id del valor de opción. De la respuesta, anota el id de la combinación (id_product_attribute) para gestionar stock.


6. Stock

El stock se gestiona en /api/stock_availables. Para producto sin combinaciones se usa id_product_attribute: 0. Para producto con combinaciones se usa el id de cada combinación.

6.1 Obtener stock de un producto

cURL de ejemplo:

curl -X GET "https://{{domain}}/api/stock_availables?display=full&filter[id_product]={{id_product}}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}"

6.2 Actualizar cantidad de stock

Usa {{id_stock_available}} (id del recurso obtenido en 6.1) y {{id_product}}.

cURL de ejemplo:

curl -X PUT "https://{{domain}}/api/stock_availables/{{id_stock_available}}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "stock_available": {
      "id": {{id_stock_available}},
      "id_product": {{id_product}},
      "id_product_attribute": 0,
      "quantity": "150",
      "depends_on_stock": 0,
      "out_of_stock": 1,
      "id_shop": 1
    }
  }'

6.3 Crear registro de stock (si no existe)

curl -X POST "https://{{domain}}/api/stock_availables" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "stock_available": {
      "id_product": {{id_product}},
      "id_product_attribute": 0,
      "quantity": "100",
      "depends_on_stock": 0,
      "out_of_stock": 2,
      "id_shop": 1
    }
  }'

7. Imágenes del producto

Las imágenes se asocian al producto (no a combinaciones individuales en este endpoint). Formato: multipart/form-data, parámetro image.

7.1 Subir una imagen

cURL de ejemplo: usa {{id_product}} y la ruta local del fichero.

curl -X POST "https://{{domain}}/api/images/products/{{id_product}}" \
  -H "Authorization: Basic {{token_encode}}" \
  -F "image=@/ruta/local/imagen.jpg"

7.2 Listar IDs de imágenes de un producto

curl -X GET "https://{{domain}}/api/images/products/{{id_product}}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}"

7.3 Eliminar una imagen

curl -X DELETE "https://{{domain}}/api/images/products/{{id_product}}/{{id_image}}" \
  -H "Authorization: Basic {{token_encode}}"

8. Precios específicos (descuentos)

Precios específicos permiten descuentos por porcentaje o monto fijo, con restricciones opcionales (fechas, cantidad mínima, grupo, etc.).

8.1 Descuento por monto fijo

cURL de ejemplo:

curl -X POST "https://{{domain}}/api/specific_prices" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "specific_price": {
        "id_shop_group": "0",
        "id_shop": "1",
        "id_cart": "0",
        "id_product": "{{id_product}}",
        "id_product_attribute": "0",
        "id_currency": "0",
        "id_country": "0",
        "id_group": "1",
        "id_customer": "0",
        "id_specific_price_rule": "0",
        "price": "-1.000000",
        "from_quantity": "1",
        "reduction": "1000",
        "reduction_tax": "0",
        "reduction_type": "amount",
        "from": "2025-11-26",
        "to": "2025-11-27"
    }
  }'

8.2 Descuento por porcentaje (ej. 5 %)

Para descuento por porcentaje (solo cambian reduction_type y reduction):

curl -X POST "https://{{domain}}/api/specific_prices" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "specific_price": {
        "id_shop_group": "0",
        "id_shop": "1",
        "id_cart": "0",
        "id_product": "{{id_product}}",
        "id_product_attribute": "0",
        "id_currency": "0",
        "id_country": "0",
        "id_group": "1",
        "id_customer": "0",
        "id_specific_price_rule": "0",
        "price": "-1.000000",
        "from_quantity": "1",
        "reduction": "0.05",
        "reduction_tax": "0",
        "reduction_type": "percentage",
        "from": "2025-11-26",
        "to": "2025-11-27"
    }
  }'
  • Porcentaje: reduction en decimal (ej. 0.05 = 5 %). Monto: reduction en unidades de moneda (ej. 1000).
  • price: -1 mantiene el precio base y aplica solo el descuento.

8.3 Listar precios específicos de un producto

curl -X GET "https://{{domain}}/api/specific_prices?filter[id_product]=[{{id_product}}]" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}"

8.4 Eliminar un precio específico

curl -X DELETE "https://{{domain}}/api/specific_prices/{{id_specific_price}}" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}"

9. Características de producto (especificaciones)

Las product_features y product_feature_values sirven para datos descriptivos (material, dimensiones, etc.), no para variantes de compra.

9.1 Listar características existentes

cURL de ejemplo:

curl -X GET "https://{{domain}}/api/product_features?display=full" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}"

9.2 Crear una característica

cURL de ejemplo:

curl -X POST "https://{{domain}}/api/product_features/" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "feature": {
        "name": {
            "language": {
                "@id": 1,
                "%": "tralalero tralala"
            }
        }
    }
  }'

Sustituye el valor de "%" por el nombre de la característica (ej. "Material").

9.3 Crear un valor de característica

cURL de ejemplo:

curl -X POST "https://{{domain}}/api/product_feature_values/" \
  -H "Content-Type: application/json" \
  -H "Authorization: Basic {{token_encode}}" \
  -d '{
    "feature_values": {
        "id_feature": 1924,
        "value": {
            "language": {
                "@id": 1,
                "%": "bombardiro cocodrilo"
            }
        }
    }
  }'

Sustituye id_feature por el id de la característica (paso 9.2) y el valor de "%" por el texto deseado (ej. "Algodón").

La asociación producto ↔ características se gestiona según la referencia de API (asociaciones del recurso producto).


Errores frecuentes al integrar

Código / Mensaje Causa habitual Qué hacer
401 – No puede activar durante el alta active: "1" en el POST de producto Enviar siempre active: "0" en el alta; activar después con PUT
401 – No se puede activar sin transportistas Producto sin carriers asignados GET /api/carriers (requiere permiso), luego PUT producto con id_carriers (ej. "91,378")
401 – No se puede activar sin imágenes Producto sin ninguna imagen Subir al menos una imagen con POST /api/images/products/{id} antes del PUT de activación
401 – Resource "carriers" not allowed La clave de API no tiene permiso carriers Pedir habilitación del recurso carriers para la clave (lectura)
422 – parameter "X" required PUT con solo id y active Incluir en el PUT los campos obligatorios del producto (name, price, id_shop_default, installments_fixed, etc.)
422 – No se puede crear o modificar sin nombre PUT sin name Incluir name (y en algunos entornos installments_fixed, id_shop_default) en el cuerpo
84 – Property AttributeGroup->name is empty Formato incorrecto en product_options Usar "@id" y "%" en name/public_name, no "id"/"value"
id_category_default debe ser "2" Categoría por defecto incorrecta en alta Usar id_category_default: "2" en el POST (y asignar más categorías en associations.categories si aplica)

Ante cualquier otro error, revisar el cuerpo de la respuesta (array errors) y la Referencia de API para el recurso afectado.


10. Resumen de endpoints por fase

Fase Método Endpoint Uso
Categorías GET /api/categories Listar categorías para asignar al producto
Carriers GET /api/carriers Listar transportistas (requiere permiso); usar IDs en id_carriers del producto
Producto POST /api/products Crear producto (nombre, referencia, precio, categorías)
Producto PUT /api/products/{id} Actualizar producto, categorías, id_carriers o activar
Opciones POST /api/product_options Crear grupo (Color, Talla, etc.)
Valores opción POST /api/product_option_values Crear valor (Rojo, M, L, etc.)
Combinaciones POST /api/combinations Crear variante producto + valores
Stock GET /api/stock_availables?filter[id_product]=X Ver stock
Stock PUT /api/stock_availables/{id} Actualizar cantidad
Stock POST /api/stock_availables Crear registro de stock
Imágenes POST /api/images/products/{id} Subir imagen
Imágenes GET /api/images/products/{id} Listar imágenes
Precios específicos POST /api/specific_prices Crear descuento
Precios específicos GET /api/specific_prices?filter[id_product]=X Listar descuentos
Características POST /api/product_features Crear característica
Características POST /api/product_feature_values Crear valor de característica

Para más detalle de campos y respuestas, consulta Productos y la Referencia de API.