---
title: "Create product"
method: POST
path: "/ecommerce/products"
---

# Create product

`POST /ecommerce/products`

## Request

- Base URL: `https://api.service.getjusto.com/v3`
- URL: `https://api.service.getjusto.com/v3/ecommerce/products`
- Auth: none declared

Crea un producto con su precio y disponibilidad en cada menú. Requiere edición de productos habilitada en la marca. Las imágenes, SEO y contenido enriquecido se editan después con PUT /ecommerce/products/{productId}.

**Cómo funcionan los menús y precios**

Un menú es una lista de precios: dice qué productos se venden y a qué precio. En el administrador se llama *menú* y en la API *precio*: cada menú es un registro de `GET /ecommerce/prices`, y su `_id` es el `menuId` que aparece en `menus` de cada producto. Una marca puede tener varios menús, por ejemplo uno general, uno para un local y uno de almuerzo.

**1. Cada pedido usa un solo menú.** Los menús no se mezclan: el cliente ve el precio y la disponibilidad que el producto tiene en el menú que se está usando.

**2. Cómo se elige el menú en la tienda online.** Se revisan los menús habilitados de mayor a menor `priority` y se usa el primero que cumple todas estas condiciones:

- `storesIds` está vacío o incluye el local del pedido. Mientras no se sepa el local, los menús con locales no aplican.
- `channels` está vacío o incluye el canal del pedido. Si el cliente aún no elige cómo recibir el pedido, se considera delivery.
- `schedule` está abierto a la hora de entrega menos el tiempo de preparación del local, o ahora si el pedido no es programado. El horario solo restringe si `availableAtPeriods` es `true`; si no, el menú aplica a toda hora, salvo los días cerrados (`closedDays`).
- Faltan al menos `daysBefore` días de calendario para esa fecha.
- `segmentIds` está vacío, o el cliente inició sesión y pertenece a alguna de esas audiencias.

Si ningún menú cumple, se usa el menú por defecto (`isDefault`), aunque no cumpla sus condiciones. Si la marca no tiene menú por defecto, se usa el de mayor `priority`. Si la marca tiene un solo menú habilitado, se usa siempre.

**3. Productos no disponibles.** Si el producto no está disponible en el menú que se usa, no aparece en la tienda. Si en el administrador tiene un mensaje de no disponible, aparece con ese mensaje, pero no se puede comprar. Un producto tampoco aparece si tiene un modificador obligatorio sin opciones disponibles en ese menú. Agotado (`out-of-stock`) es otra cosa: se marca por local, y el producto aparece como agotado, salvo que la marca active *Ocultar productos no disponibles o sin stock*: entonces los agotados no aparecen.

**4. Cada menú tiene su propio precio.** Cambiar el precio en un menú no cambia los demás. Para cambiarlo en toda la marca, cámbialo en cada menú donde el producto está disponible. Para cambiarlo solo en un local, canal u horario, usa el punto 2 para saber qué menú se usa ahí.

**5. Descuentos.** `discountPrice` es el precio final que paga el cliente, no un monto ni un porcentaje, y no puede ser mayor que el precio: si bajas `price` por debajo del descuento guardado, envía también `discountPrice`. Si es menor que el precio, la tienda muestra el precio normal tachado. En las respuestas viene como `discount`. Enviar `discountPrice` deja un solo descuento, y `null` lo quita. En el administrador se pueden guardar varios descuentos seguidos: en ese caso `discount` es el primero, pero el cliente paga el último.

**6. Los cambios no son instantáneos.** La tienda se actualiza en segundo plano, y el menú elegido para cada cliente se guarda hasta 15 minutos, así que un cambio en las condiciones de un menú puede tardar ese tiempo en verse.

## Request body

- ApiProductCreateInput: Datos del producto nuevo. Sin menus, el producto se crea sin precio y no se muestra en la tienda. Los menús y sus IDs están en GET /ecommerce/prices.
  - `name` string, required: Nombre visible del producto.
  - `internalName` string: Nombre interno del producto.
  - `description` string: Descripción visible del producto.
  - `externalId` string: ID externo único en la marca.
  - `categoriesIds` string[]: IDs Justo o externos de las categorías del producto.
  - `modifiersIds` string[]: IDs Justo o externos de los modificadores del producto.
  - `menus` object[]: Precio y disponibilidad en cada menú donde se venderá. Incluye todos los menús que pueden aplicar en los locales y canales donde debe aparecer.
    - `menuId` string, required: ID Justo o externo del menú.
    - `price` number, required: Precio base en la moneda de la marca. 0 significa gratis. Es obligatorio si el producto aún no tiene precio en ese menú.
    - `discountPrice` number, nullable: Precio con descuento: el precio final rebajado, menor o igual al precio base. No es un monto ni un porcentaje. Reemplaza los descuentos guardados en ese menú; null los quita. Si bajas price por debajo del precio con descuento actual, envía también discountPrice o null.
    - `available` boolean: Si el producto se vende en ese menú. Al asignar un precio en un menú nuevo sin este campo, queda disponible.

## Response `200`

The OpenAPI spec

- object
  - `success` boolean
  - `data` ApiListingProduct: Producto del catálogo.
    - `productId` string: ID Justo del producto.
    - `importId` string: ID de importación del producto.
    - `name` string: Nombre del producto.
    - `internalName` string: Nombre interno del producto.
    - `description` string: Descripción visible del producto.
    - `seoTitle` string, nullable: Título SEO independiente del nombre. Null o texto vacío restaura el título automático.
    - `seoDescription` string, nullable: Metadescripción independiente de la descripción. Null o texto vacío restaura el valor automático.
    - `seoImageURL` string, nullable: URL absoluta http o https sin credenciales, para SEO y enlaces compartidos. Null o texto vacío restaura la imagen automática. No modifica la galería.
    - `richContent` string, nullable: HTML sanitizado, disponible en GET individual y respuesta de PUT. Null elimina el contenido. Admite texto, imágenes, galerías, tablas y acordiones; elimina scripts, estilos y clases.
    - `richContentPosition` 'beforeModifiers' | 'afterModifiers' | 'null', nullable: Posición del contenido respecto a los modificadores. Null usa beforeModifiers.
    - `hasRichContent` boolean: Indica si tiene contenido enriquecido. El listado omite el HTML; consulta el detalle para obtenerlo.
    - `url` string: URL pública del producto.
    - `partialUrl` string: Path público del producto.
    - `categoriesNames` string[]: Nombres de categorías asociadas.
    - `categoriesIds` string[]: IDs de categorías asociadas.
    - `modifiersIds` string[]: IDs de modificadores asociados.
    - `externalId` string: ID externo configurado por la marca.
    - `metadata` object: Metadata del item escrita por API v3.
    - `images` string[]: URLs de imágenes del producto.
    - `menus` object[]: Precio y disponibilidad en cada menú. El cliente ve sólo los del menú que aplica en su pedido; ver GET /ecommerce/prices.
      - `menuId` string: ID Justo del menú (_id en GET /ecommerce/prices).
      - `price` number: Precio base en este menú. Si el item no tiene configuración en este menú, es 0 y available no viene.
      - `discount` number, nullable: Precio con descuento: el precio final rebajado, no un monto ni un porcentaje. null si no tiene. Si en el administrador se guardaron varios descuentos seguidos, es el primero, pero el cliente paga el último.
      - `available` boolean: true si se vende en este menú. Si es false o no viene, no se vende: el item no aparece mientras se use este menú, salvo que tenga un mensaje de no disponible en el administrador; entonces aparece con ese mensaje, pero no se puede comprar.
      - `externalId` string: ID externo del producto en este menú: el de reemplazo si se configuró; si no, el externalId del producto.

## Other responses

- `400`: Errors

## Changes

- **2026-10-31** `4ad06bd631ce`: 1 info
  - endpoint added

[Operation history](https://skmtc.dev/getjusto/apis/justo-api/changes/ecommerce/products/post.md)

---

[API](https://skmtc.dev/getjusto/apis/justo-api.md) - [All operations](https://skmtc.dev/getjusto/apis/justo-api/llms.txt) - [OpenAPI document](https://skmtc.dev/getjusto/apis/justo-api/revisions/c810bd8246fd?raw)
