Skip to main content
POST
https://ecommerce.jelou.ai
/
api
/
v2
/
apps
/
{app_id}
/
batch
/
products
/
upsert_by_sku
curl -X POST "https://ecommerce.jelou.ai/api/v2/apps/{app_id}/batch/products/upsert_by_sku" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "resources": [
      {
        "sku": "CAM-BLU",
        "name": "Camiseta Básica Azul",
        "description": "Camiseta de algodón 100% premium, corte regular",
        "price": 29.99,
        "has_tax": true,
        "status": true,
        "stock_type": "limited",
        "stock": 150,
        "product_url": "https://mi-tienda.com/camiseta-basica-azul",
        "discount_type": "percentage",
        "discount": 10,
        "branch": "SUC-CENTRO",
        "categories": ["Ropa", "Camisetas"],
        "images": [
          "https://mi-tienda.com/images/camiseta-azul-front.jpg",
          "https://mi-tienda.com/images/camiseta-azul-back.jpg"
        ],
        "variations": [
          {
            "sku": "CAM-BLU-S",
            "price": 29.99,
            "attributes": [
              { "name": "Talla", "value": "S" },
              { "name": "Color", "value": "Azul" }
            ]
          },
          {
            "sku": "CAM-BLU-M",
            "price": 29.99,
            "attributes": [
              { "name": "Talla", "value": "M" },
              { "name": "Color", "value": "Azul" }
            ]
          },
          {
            "sku": "CAM-BLU-L",
            "price": 31.99,
            "attributes": [
              { "name": "Talla", "value": "L" },
              { "name": "Color", "value": "Azul" }
            ],
            "images": [
              "https://mi-tienda.com/images/camiseta-azul-L.jpg"
            ]
          }
        ]
      },
      {
        "sku": "PAN-NEG-M",
        "name": "Pantalón Negro",
        "price": 49.99,
        "branch": "SUC-NORTE",
        "categories": ["Ropa", "Pantalones"]
      },
      {
        "sku": "PIZZA-FAMILIAR",
        "name": "Pizza Familiar Pepperoni",
        "description": "Pizza familiar de pepperoni con masa artesanal",
        "price": 18.99,
        "stock_type": "unlimited",
        "branch": "SUC-NORTE",
        "categories": ["Pizzas", "Promociones"],
        "images": ["https://ejemplo.com/pizza-pepperoni.jpg"],
        "modifier_groups": [
          {
            "code": "bebidas",
            "name": "Escoja su Bebida",
            "min_quantity": 1,
            "max_quantity": 1,
            "is_required": true,
            "options": [
              { "code": "coca-1l", "name": "Coca Cola 1L", "price": 0 },
              { "code": "sprite-1l", "name": "Sprite 1L", "price": 0 },
              { "code": "fanta-1l", "name": "Fanta 1L", "price": 0.50 }
            ]
          },
          {
            "code": "extras",
            "name": "Ingredientes Extra",
            "min_quantity": 0,
            "max_quantity": 5,
            "max_per_option": 2,
            "is_required": false,
            "options": [
              { "code": "queso-extra", "name": "Queso Extra", "price": 1.50 },
              { "code": "jamon", "name": "Jamón", "price": 2.00 },
              { "code": "aceitunas", "name": "Aceitunas", "price": 1.00 }
            ]
          }
        ]
      }
    ]
  }'
{
  "message": "Batch upsert process initiated successfully",
  "count": 3,
  "jobs": 3
}
Puedes crear o actualizar productos en lote según su SKU. Si un producto con el SKU especificado ya existe, se actualiza; si no, se crea. Los productos pueden asignarse a una sucursal, tener múltiples variaciones y grupos de modificadores.
app_id
string
required
ID de tu tienda en Jelou Shop.
resources
object[]
required
Lista de productos a crear o actualizar (máx. 500 por solicitud).

Campos del producto

Cada objeto dentro de resources acepta los siguientes campos:
sku
string
required
Identificador único del producto (máx. 255 caracteres).
name
string
required
Nombre del producto (máx. 255 caracteres).
price
number
required
Precio del producto (mín. 0).
description
string
Descripción del producto.
has_tax
boolean
default:"true"
Indica si el precio incluye impuestos.
status
boolean
default:"true"
Estado del producto (activo/inactivo).
stock_type
string
default:"unlimited"
Tipo de inventario: limited o unlimited.
stock
number
Cantidad disponible. Aplica solo cuando stock_type es limited.
product_url
string
URL del producto en tu tienda (máx. 2048 caracteres).
discount_type
string
Tipo de descuento: value (monto fijo) o percentage.
discount
number
Valor del descuento (mín. 0).
categories
string[]
Lista de nombres de categorías. Se crean automáticamente si no existen.
images
string[]
Lista de URLs de imágenes públicas del producto.
branch
string
Código de la sucursal a la que se asigna el producto. La sucursal debe existir previamente.
La sucursal debe estar creada antes de asignarla a un producto. Usa el endpoint Crear sucursal para registrarla primero.
variations
object[]
Lista de variaciones del producto.
modifier_groups
object[]
Grupos de modificadores (add-ons) del producto. Comunes en delivery de comida (ej: “Escoja las Bebidas”, “Elige las salsas”). Si el campo está ausente, se preservan los modificadores existentes. Si es un array vacío [], se eliminan todos. Si tiene datos, se reemplazan completamente.
Los modificadores se almacenan en el producto y se devuelven automáticamente en todos los endpoints que retornan productos.

Ejemplo completo

Este ejemplo crea tres productos: una camiseta con variaciones de talla, un pantalón simple y una pizza con grupos de modificadores.
curl -X POST "https://ecommerce.jelou.ai/api/v2/apps/{app_id}/batch/products/upsert_by_sku" \
  -H "Authorization: Bearer <API_KEY>" \
  -H "Content-Type: application/json" \
  -d '{
    "resources": [
      {
        "sku": "CAM-BLU",
        "name": "Camiseta Básica Azul",
        "description": "Camiseta de algodón 100% premium, corte regular",
        "price": 29.99,
        "has_tax": true,
        "status": true,
        "stock_type": "limited",
        "stock": 150,
        "product_url": "https://mi-tienda.com/camiseta-basica-azul",
        "discount_type": "percentage",
        "discount": 10,
        "branch": "SUC-CENTRO",
        "categories": ["Ropa", "Camisetas"],
        "images": [
          "https://mi-tienda.com/images/camiseta-azul-front.jpg",
          "https://mi-tienda.com/images/camiseta-azul-back.jpg"
        ],
        "variations": [
          {
            "sku": "CAM-BLU-S",
            "price": 29.99,
            "attributes": [
              { "name": "Talla", "value": "S" },
              { "name": "Color", "value": "Azul" }
            ]
          },
          {
            "sku": "CAM-BLU-M",
            "price": 29.99,
            "attributes": [
              { "name": "Talla", "value": "M" },
              { "name": "Color", "value": "Azul" }
            ]
          },
          {
            "sku": "CAM-BLU-L",
            "price": 31.99,
            "attributes": [
              { "name": "Talla", "value": "L" },
              { "name": "Color", "value": "Azul" }
            ],
            "images": [
              "https://mi-tienda.com/images/camiseta-azul-L.jpg"
            ]
          }
        ]
      },
      {
        "sku": "PAN-NEG-M",
        "name": "Pantalón Negro",
        "price": 49.99,
        "branch": "SUC-NORTE",
        "categories": ["Ropa", "Pantalones"]
      },
      {
        "sku": "PIZZA-FAMILIAR",
        "name": "Pizza Familiar Pepperoni",
        "description": "Pizza familiar de pepperoni con masa artesanal",
        "price": 18.99,
        "stock_type": "unlimited",
        "branch": "SUC-NORTE",
        "categories": ["Pizzas", "Promociones"],
        "images": ["https://ejemplo.com/pizza-pepperoni.jpg"],
        "modifier_groups": [
          {
            "code": "bebidas",
            "name": "Escoja su Bebida",
            "min_quantity": 1,
            "max_quantity": 1,
            "is_required": true,
            "options": [
              { "code": "coca-1l", "name": "Coca Cola 1L", "price": 0 },
              { "code": "sprite-1l", "name": "Sprite 1L", "price": 0 },
              { "code": "fanta-1l", "name": "Fanta 1L", "price": 0.50 }
            ]
          },
          {
            "code": "extras",
            "name": "Ingredientes Extra",
            "min_quantity": 0,
            "max_quantity": 5,
            "max_per_option": 2,
            "is_required": false,
            "options": [
              { "code": "queso-extra", "name": "Queso Extra", "price": 1.50 },
              { "code": "jamon", "name": "Jamón", "price": 2.00 },
              { "code": "aceitunas", "name": "Aceitunas", "price": 1.00 }
            ]
          }
        ]
      }
    ]
  }'
{
  "message": "Batch upsert process initiated successfully",
  "count": 3,
  "jobs": 3
}
Reemplaza {app_id} con el ID de tu tienda y <API_KEY> con el token proporcionado por Jelou.

Comportamiento

El endpoint retorna 202 Accepted inmediatamente. Los productos se procesan en segundo plano.
Si el código de sucursal no coincide con ninguna sucursal de la tienda, el producto se crea sin sucursal asignada. No produce error.
Si una categoría no existe, se crea automáticamente dentro de la tienda y la sucursal correspondiente.
Las imágenes se descargan y procesan en segundo plano después de la creación del producto.
Las variaciones se identifican por su SKU. Si ya existe una variación con ese SKU, se actualiza en lugar de crear una nueva.
Si modifier_groups está ausente en el payload, se preservan los modificadores existentes. Si es un array vacío [], se eliminan todos. Si tiene datos, se reemplazan completamente.

Errores de validación

Si los datos no cumplen las reglas de validación, la API responde con 422 y detalla los campos con error.
{
  "message": "The resources field is required.",
  "errors": {
    "resources": ["The resources field is required."]
  }
}
CampoMensaje
resourcesAt least one product is required.
resourcesCannot process more than 500 products at once.
resources.*.skuEach product must have a SKU.
resources.*.nameEach product must have a name.
resources.*.priceEach product must have a price. / Price cannot be negative.
resources.*.stock_typeStock type must be either limited or unlimited.
resources.*.images.*Each image must be a valid URL.
resources.*.modifier_groups.*.codeEach modifier group must have a code.
resources.*.modifier_groups.*.nameEach modifier group must have a name.
resources.*.modifier_groups.*.optionsEach modifier group must have at least one option.
resources.*.modifier_groups.*.options.*.codeEach modifier option must have a code.
resources.*.modifier_groups.*.options.*.nameEach modifier option must have a name.

Límites

  • Máximo 500 productos por solicitud.
  • Todos los productos se validan antes de procesarse.