{
"success": "false",
"error": {
"error": "error",
"message": "The request has an error"
}
}
Catálogo
Crear producto
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/.
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.
{"docsConfig":{"$schema":"https://mintlify.com/docs.json","theme":"mint","name":"Justo Docs","colors":{"primary":"#3b82f6","light":"#AE87FF","dark":"#0D001D"},"favicon":"https://mintcdn.com/justo/3q6RHbTj2xkukgKt/favicon.png?fit=max\u0026auto=format\u0026n=3q6RHbTj2xkukgKt\u0026q=85\u0026s=c4ae41602a6ac806c1294ba3cf13544e","logo":{"light":"https://mintcdn.com/justo/kGzZskwUmUVkF7RU/logo/logo-dark.svg?fit=max\u0026auto=format\u0026n=kGzZskwUmUVkF7RU\u0026q=85\u0026s=45816fc3a2198f90b32f320e33e24037","dark":"https://mintcdn.com/justo/kGzZskwUmUVkF7RU/logo/logo-white.svg?fit=max\u0026auto=format\u0026n=kGzZskwUmUVkF7RU\u0026q=85\u0026s=7472c73d4e8984a86c9ca5acc0c36981"},"api":{"playground":{"display":"interactive"},"mdx":{"server":null,"auth":{"method":"bearer","name":null}}},"background":{"decoration":null,"color":{"light":null,"dark":"#090014"}},"navbar":{"links":[{"label":"Ayuda","href":"mailto:tecnologia@getjusto.com"}],"primary":{"type":"button","label":"Justo","href":"https://getjusto.com"}},"footer":{"socials":{"github":"https://github.com/getjusto","linkedin":"https://www.linkedin.com/company/getjusto"}},"integrations":{"intercom":{"appId":"ohd982w5"}},"styling":{"latex":false},"navigation":{"global":{"anchors":[{"anchor":"Developer Portal","href":"https://developers.getjusto.com","icon":"code"}]},"pages":[]}},"deployment":{"deploymentMetadataValue":{"subdomain":"justo","hasAudioNarration":false,"actualSubdomain":"justo","customDomains":["docs.getjusto.com"],"gitSource":{"type":"github","owner":"getjusto","repo":"docs","deployBranch":"main","contentDirectory":"","isPrivate":false,"mountPath":"","label":""},"chroma":{"liveDeploymentHistoryId":"6abaafb5964c11dd724584fc","collectionId":"79125b6a-c4b5-4a10-a4eb-8b5abd6687c8","schemaVersion":"v3","latestBuiltDeploymentHistoryId":"6abaafb5964c11dd724584fc"},"entitlements":{"AI_CHAT":{"status":"ENABLED"},"WEB_MCP":{"status":"ENABLED"},"NARRATION":{"status":"ENABLED"}},"buildId":"6ae5e215302fef4badcdfa20","clientVersion":"0.0.4043","searchFilterCounts":[{"language":"default","tag":"PDV","count":122},{"language":"default","tag":"API Endpoints","count":109},{"language":"default","tag":"Config","count":100},{"language":"default","tag":"Servicios","count":80},{"language":"default","tag":"Ecommerce","count":54},{"language":"default","tag":"Administración de inventario","count":52},{"language":"default","tag":"Base","count":49},{"language":"default","tag":"API V2.2","count":46},{"language":"default","tag":"Catálogo","count":24},{"language":"default","tag":"Ordering API","count":23}]},"assistantConfig":{},"basePath":"","hasChatPermissions":true,"hasWebMcpPermissions":true,"toggles":[{"name":"kill-isr","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-mintlify-slack","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"agent-integrations-settings","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-pr-grouping","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"custom-prefix","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"analytics-v7","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"user-flows-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"no-publish-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-onboarding","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"llms-txt-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving-live","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"stripTemperatureMiddleware","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"support-platform-pylon-zendesk","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"snapshot-serving","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"instant-rollback","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications-server","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"granular-notifications","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automations-fable","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fixed-ai-action-pricing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"automation-resolve-merge-conflict","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"scoped-publishing","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"mintql","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"page-level-analytics","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"editor-version-history-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-page-v2","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"full-page-search","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workspace-projects","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"assistant-v5","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"byok-sep-25","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"fork-pr-previews","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"revalidation-jwt","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"vite-origin","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"billing-updated-9-15","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-sso-scim","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"hobby-abuse-scan","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"dashboard-inbox","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-signup","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"turbopuffer-dual-write","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"workos-enabled","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"approve-review-flow","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false},{"name":"sso-setup-deadline-banner","enabled":true,"variant":{"name":"disabled","enabled":false,"feature_enabled":true},"impressionData":false}],"googleFontsInlined":false},"customCss":[],"page":{"pagePath":"docs/menu-catalog/endpoints/catalog/create-product","slug":"/docs/menu-catalog/endpoints/catalog/create-product","pageMetadata":{"title":"Crear producto","openapi":"post /ecommerce/products","description":"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}.\n\n**Cómo funcionan los menús y precios**\n\nUn 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.\n\n**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.\n\n**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:\n\n- `storesIds` está vacío o incluye el local del pedido. Mientras no se sepa el local, los menús con locales no aplican.\n- `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.\n- `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`).\n- Faltan al menos `daysBefore` días de calendario para esa fecha.\n- `segmentIds` está vacío, o el cliente inició sesión y pertenece a alguna de esas audiencias.\n\nSi 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.\n\n**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.\n\n**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í.\n\n**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.\n\n**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.","href":"/docs/menu-catalog/endpoints/catalog/create-product"},"description":{"compiledSource":"\"use strict\";\nconst {Fragment: _Fragment, jsx: _jsx, jsxs: _jsxs} = arguments[0];\nconst {useMDXComponents: _provideComponents} = arguments[0];\nfunction _createMdxContent(props) {\n const _components = {\n code: \"code\",\n em: \"em\",\n li: \"li\",\n p: \"p\",\n strong: \"strong\",\n ul: \"ul\",\n ..._provideComponents(),\n ...props.components\n };\n return _jsxs(_Fragment, {\n children: [_jsxs(_components.p, {\n children: [\"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/\", \".\"]\n }), \"\\n\", _jsx(_components.p, {\n children: _jsx(_components.strong, {\n children: \"Cómo funcionan los menús y precios\"\n })\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Un menú es una lista de precios: dice qué productos se venden y a qué precio. En el administrador se llama \", _jsx(_components.em, {\n children: \"menú\"\n }), \" y en la API \", _jsx(_components.em, {\n children: \"precio\"\n }), \": cada menú es un registro de \", _jsx(_components.code, {\n children: \"GET /ecommerce/prices\"\n }), \", y su \", _jsx(_components.code, {\n children: \"_id\"\n }), \" es el \", _jsx(_components.code, {\n children: \"menuId\"\n }), \" que aparece en \", _jsx(_components.code, {\n children: \"menus\"\n }), \" de cada producto. Una marca puede tener varios menús, por ejemplo uno general, uno para un local y uno de almuerzo.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"1. Cada pedido usa un solo menú.\"\n }), \" 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.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"2. Cómo se elige el menú en la tienda online.\"\n }), \" Se revisan los menús habilitados de mayor a menor \", _jsx(_components.code, {\n children: \"priority\"\n }), \" y se usa el primero que cumple todas estas condiciones:\"]\n }), \"\\n\", _jsxs(_components.ul, {\n children: [\"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"storesIds\"\n }), \" está vacío o incluye el local del pedido. Mientras no se sepa el local, los menús con locales no aplican.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"channels\"\n }), \" está vacío o incluye el canal del pedido. Si el cliente aún no elige cómo recibir el pedido, se considera delivery.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"schedule\"\n }), \" 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 \", _jsx(_components.code, {\n children: \"availableAtPeriods\"\n }), \" es \", _jsx(_components.code, {\n children: \"true\"\n }), \"; si no, el menú aplica a toda hora, salvo los días cerrados (\", _jsx(_components.code, {\n children: \"closedDays\"\n }), \").\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [\"Faltan al menos \", _jsx(_components.code, {\n children: \"daysBefore\"\n }), \" días de calendario para esa fecha.\"]\n }), \"\\n\", _jsxs(_components.li, {\n children: [_jsx(_components.code, {\n children: \"segmentIds\"\n }), \" está vacío, o el cliente inició sesión y pertenece a alguna de esas audiencias.\"]\n }), \"\\n\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [\"Si ningún menú cumple, se usa el menú por defecto (\", _jsx(_components.code, {\n children: \"isDefault\"\n }), \"), aunque no cumpla sus condiciones. Si la marca no tiene menú por defecto, se usa el de mayor \", _jsx(_components.code, {\n children: \"priority\"\n }), \". Si la marca tiene un solo menú habilitado, se usa siempre.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"3. Productos no disponibles.\"\n }), \" 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 (\", _jsx(_components.code, {\n children: \"out-of-stock\"\n }), \") es otra cosa: se marca por local, y el producto aparece como agotado, salvo que la marca active \", _jsx(_components.em, {\n children: \"Ocultar productos no disponibles o sin stock\"\n }), \": entonces los agotados no aparecen.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"4. Cada menú tiene su propio precio.\"\n }), \" 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í.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"5. Descuentos.\"\n }), \" \", _jsx(_components.code, {\n children: \"discountPrice\"\n }), \" es el precio final que paga el cliente, no un monto ni un porcentaje, y no puede ser mayor que el precio: si bajas \", _jsx(_components.code, {\n children: \"price\"\n }), \" por debajo del descuento guardado, envía también \", _jsx(_components.code, {\n children: \"discountPrice\"\n }), \". Si es menor que el precio, la tienda muestra el precio normal tachado. En las respuestas viene como \", _jsx(_components.code, {\n children: \"discount\"\n }), \". Enviar \", _jsx(_components.code, {\n children: \"discountPrice\"\n }), \" deja un solo descuento, y \", _jsx(_components.code, {\n children: \"null\"\n }), \" lo quita. En el administrador se pueden guardar varios descuentos seguidos: en ese caso \", _jsx(_components.code, {\n children: \"discount\"\n }), \" es el primero, pero el cliente paga el último.\"]\n }), \"\\n\", _jsxs(_components.p, {\n children: [_jsx(_components.strong, {\n children: \"6. Los cambios no son instantáneos.\"\n }), \" 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.\"]\n })]\n });\n}\nfunction MDXContent(props = {}) {\n const {wrapper: MDXLayout} = {\n ..._provideComponents(),\n ...props.components\n };\n return MDXLayout ? _jsx(MDXLayout, {\n ...props,\n children: _jsx(_createMdxContent, {\n ...props\n })\n }) : _createMdxContent(props);\n}\nreturn {\n default: MDXContent\n};\n","frontmatter":{},"scope":{}},"pageType":"default","mdx":{"mdxSource":{"compiledSource":"\"use strict\";const{Fragment:_Fragment,jsx:_jsx}=arguments[0];const{useMDXComponents:_provideComponents}=arguments[0];function _createMdxContent(props){return _jsx(_Fragment,{})}function MDXContent(props={}){const{wrapper:MDXLayout}={..._provideComponents(),...props.components};return MDXLayout?_jsx(MDXLayout,{...props,children:_jsx(_createMdxContent,{...props})}):_createMdxContent(props)}return{default:MDXContent}","frontmatter":{},"scope":{"config":{},"pageMetadata":{"title":"Crear producto","openapi":"post /ecommerce/products","description":"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}.\n\n**Cómo funcionan los menús y precios**\n\nUn 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.\n\n**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.\n\n**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:\n\n- `storesIds` está vacío o incluye el local del pedido. Mientras no se sepa el local, los menús con locales no aplican.\n- `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.\n- `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`).\n- Faltan al menos `daysBefore` días de calendario para esa fecha.\n- `segmentIds` está vacío, o el cliente inició sesión y pertenece a alguna de esas audiencias.\n\nSi 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.\n\n**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.\n\n**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í.\n\n**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.\n\n**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.","href":"/docs/menu-catalog/endpoints/catalog/create-product"}}},"mdxSourceWithNoJs":null},"mdxExtracts":{"tableOfContents":[],"codeExamples":{}},"jsLinks":[],"openApiReferenceData":{"operation":{"summary":"Create product","description":"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}.\n\n**Cómo funcionan los menús y precios**\n\nUn 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.\n\n**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.\n\n**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:\n\n- `storesIds` está vacío o incluye el local del pedido. Mientras no se sepa el local, los menús con locales no aplican.\n- `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.\n- `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`).\n- Faltan al menos `daysBefore` días de calendario para esa fecha.\n- `segmentIds` está vacío, o el cliente inició sesión y pertenece a alguna de esas audiencias.\n\nSi 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.\n\n**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.\n\n**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í.\n\n**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.\n\n**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.","requestBody":"4ee661e7-b251-4409-950d-c996e0893e37","responses":{"200":"c0107566-5abd-44ef-8e0b-8a03d1e1d75d","400":"a1898574-5870-4a6a-b477-e9e9703156d9"},"method":"post","type":"path","servers":["4ae2af61-c215-4cae-8fa3-a789c2e95d34"],"security":[],"path":"/ecommerce/products","baseUrlOptions":["https://api.service.getjusto.com/v3"],"title":"Create product","codeSamples":[],"requiredOnlyExamples":false,"requestExampleType":"generated","responseExampleType":"generated"},"dependencies":{"parameters":{},"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","description":"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.","required":["name"],"additionalProperties":false,"properties":{"name":{"type":"string","minLength":1,"description":"Nombre visible del producto.","isRequired":true,"uniqueKey":"name","typeLabel":"string"},"internalName":{"type":"string","description":"Nombre interno del producto.","uniqueKey":"internalName","typeLabel":"string"},"description":{"type":"string","description":"Descripción visible del producto.","uniqueKey":"description","typeLabel":"string"},"externalId":{"type":"string","description":"ID externo único en la marca.","uniqueKey":"externalId","typeLabel":"string"},"categoriesIds":{"type":"array","description":"IDs Justo o externos de las categorías del producto.","items":{"type":"string","uniqueKey":"categoriesIds.items.[INDEX]","typeLabel":"string"},"uniqueKey":"categoriesIds","typeLabel":"string[]"},"modifiersIds":{"type":"array","description":"IDs Justo o externos de los modificadores del producto.","items":{"type":"string","uniqueKey":"modifiersIds.items.[INDEX]","typeLabel":"string"},"uniqueKey":"modifiersIds","typeLabel":"string[]"},"menus":{"type":"array","description":"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.","items":{"type":"object","required":["menuId","price"],"additionalProperties":false,"properties":{"menuId":{"type":"string","description":"ID Justo o externo del menú.","isRequired":true,"uniqueKey":"menus.items.[INDEX].menuId","typeLabel":"string"},"price":{"type":"number","minimum":0,"description":"Precio base en la moneda de la marca. 0 significa gratis. Es obligatorio si el producto aún no tiene precio en ese menú.","isRequired":true,"uniqueKey":"menus.items.[INDEX].price","typeLabel":"number"},"discountPrice":{"oneOf":[{"type":"number","minimum":0,"description":"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.","uniqueKey":"menus.items.[INDEX].discountPrice.oneOf.0","typeLabel":"number"},{"type":"null","minimum":0,"description":"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.","uniqueKey":"menus.items.[INDEX].discountPrice.oneOf.1","typeLabel":"null"}],"uniqueKey":"menus.items.[INDEX].discountPrice","typeLabel":"number | null"},"available":{"type":"boolean","description":"Si el producto se vende en ese menú. Al asignar un precio en un menú nuevo sin este campo, queda disponible.","uniqueKey":"menus.items.[INDEX].available","typeLabel":"boolean"}},"uniqueKey":"menus.items.[INDEX]","typeLabel":"object"},"uniqueKey":"menus","typeLabel":"object[]"}},"example":{"name":"Torta de chocolate","description":"Porción individual.","categoriesIds":["ID_CATEGORIA"],"menus":[{"menuId":"ID_PRECIO","price":4990}]},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"name":"Torta de chocolate","description":"Porción individual.","categoriesIds":["ID_CATEGORIA"],"menus":[{"menuId":"ID_PRECIO","price":4990}]}}},"exampleType":"generated"}},"exampleType":"generated"},"responses":{"c0107566-5abd-44ef-8e0b-8a03d1e1d75d":{"description":"The OpenAPI spec","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":true,"uniqueKey":"success","typeLabel":"boolean"},"data":{"type":"object","description":"Producto del catálogo.","properties":{"productId":{"type":"string","description":"ID Justo del producto.","uniqueKey":"data.productId","typeLabel":"string"},"importId":{"type":"string","description":"ID de importación del producto.","uniqueKey":"data.importId","typeLabel":"string"},"name":{"type":"string","description":"Nombre del producto.","uniqueKey":"data.name","typeLabel":"string"},"internalName":{"type":"string","description":"Nombre interno del producto.","uniqueKey":"data.internalName","typeLabel":"string"},"description":{"type":"string","description":"Descripción visible del producto.","uniqueKey":"data.description","typeLabel":"string"},"seoTitle":{"oneOf":[{"type":"string","maxLength":300,"description":"Título SEO independiente del nombre. Null o texto vacío restaura el título automático.","uniqueKey":"data.seoTitle.oneOf.0","typeLabel":"string"},{"type":"null","maxLength":300,"description":"Título SEO independiente del nombre. Null o texto vacío restaura el título automático.","uniqueKey":"data.seoTitle.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.seoTitle","typeLabel":"string | null"},"seoDescription":{"oneOf":[{"type":"string","maxLength":1000,"description":"Metadescripción independiente de la descripción. Null o texto vacío restaura el valor automático.","uniqueKey":"data.seoDescription.oneOf.0","typeLabel":"string"},{"type":"null","maxLength":1000,"description":"Metadescripción independiente de la descripción. Null o texto vacío restaura el valor automático.","uniqueKey":"data.seoDescription.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.seoDescription","typeLabel":"string | null"},"seoImageURL":{"oneOf":[{"type":"string","maxLength":2048,"description":"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.","uniqueKey":"data.seoImageURL.oneOf.0","typeLabel":"string"},{"type":"null","maxLength":2048,"description":"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.","uniqueKey":"data.seoImageURL.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.seoImageURL","typeLabel":"string | null"},"richContent":{"oneOf":[{"type":"string","maxLength":50000,"description":"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.","uniqueKey":"data.richContent.oneOf.0","typeLabel":"string"},{"type":"null","maxLength":50000,"description":"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.","uniqueKey":"data.richContent.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.richContent","typeLabel":"string | null"},"richContentPosition":{"oneOf":[{"type":"string","enum":["beforeModifiers","afterModifiers",null],"description":"Posición del contenido respecto a los modificadores. Null usa beforeModifiers.","uniqueKey":"data.richContentPosition.oneOf.0","typeLabel":"enum\u003cstring>"},{"type":"null","enum":["beforeModifiers","afterModifiers",null],"description":"Posición del contenido respecto a los modificadores. Null usa beforeModifiers.","uniqueKey":"data.richContentPosition.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.richContentPosition","typeLabel":"enum\u003cstring> | null"},"hasRichContent":{"type":"boolean","description":"Indica si tiene contenido enriquecido. El listado omite el HTML; consulta el detalle para obtenerlo.","uniqueKey":"data.hasRichContent","typeLabel":"boolean"},"url":{"type":"string","description":"URL pública del producto.","uniqueKey":"data.url","typeLabel":"string"},"partialUrl":{"type":"string","description":"Path público del producto.","uniqueKey":"data.partialUrl","typeLabel":"string"},"categoriesNames":{"type":"array","description":"Nombres de categorías asociadas.","items":{"type":"string","uniqueKey":"data.categoriesNames.items.[INDEX]","typeLabel":"string"},"uniqueKey":"data.categoriesNames","typeLabel":"string[]"},"categoriesIds":{"type":"array","description":"IDs de categorías asociadas.","items":{"type":"string","uniqueKey":"data.categoriesIds.items.[INDEX]","typeLabel":"string"},"uniqueKey":"data.categoriesIds","typeLabel":"string[]"},"modifiersIds":{"type":"array","description":"IDs de modificadores asociados.","items":{"type":"string","uniqueKey":"data.modifiersIds.items.[INDEX]","typeLabel":"string"},"uniqueKey":"data.modifiersIds","typeLabel":"string[]"},"externalId":{"type":"string","description":"ID externo configurado por la marca.","uniqueKey":"data.externalId","typeLabel":"string"},"metadata":{"type":"object","description":"Metadata del item escrita por API v3.","additionalProperties":true,"uniqueKey":"data.metadata","typeLabel":"object"},"images":{"type":"array","description":"URLs de imágenes del producto.","items":{"type":"string","uniqueKey":"data.images.items.[INDEX]","typeLabel":"string"},"uniqueKey":"data.images","typeLabel":"string[]"},"menus":{"type":"array","description":"Precio y disponibilidad en cada menú. El cliente ve sólo los del menú que aplica en su pedido; ver GET /ecommerce/prices.","items":{"type":"object","description":"Precio y disponibilidad del item en un menú (precio). Viene una entrada por cada menú de la marca, también los deshabilitados. En las opciones de modificador solo vienen menuId, price y available.","properties":{"menuId":{"type":"string","description":"ID Justo del menú (_id en GET /ecommerce/prices).","uniqueKey":"data.menus.items.[INDEX].menuId","typeLabel":"string"},"price":{"type":"number","description":"Precio base en este menú. Si el item no tiene configuración en este menú, es 0 y available no viene.","uniqueKey":"data.menus.items.[INDEX].price","typeLabel":"number"},"discount":{"oneOf":[{"type":"number","description":"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.","uniqueKey":"data.menus.items.[INDEX].discount.oneOf.0","typeLabel":"number"},{"type":"null","description":"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.","uniqueKey":"data.menus.items.[INDEX].discount.oneOf.1","typeLabel":"null"}],"uniqueKey":"data.menus.items.[INDEX].discount","typeLabel":"number | null"},"available":{"type":"boolean","description":"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.","uniqueKey":"data.menus.items.[INDEX].available","typeLabel":"boolean"},"externalId":{"type":"string","description":"ID externo del producto en este menú: el de reemplazo si se configuró; si no, el externalId del producto.","uniqueKey":"data.menus.items.[INDEX].externalId","typeLabel":"string"}},"additionalProperties":true,"uniqueKey":"data.menus.items.[INDEX]","typeLabel":"object"},"uniqueKey":"data.menus","typeLabel":"object[]"}},"uniqueKey":"data","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"success":true,"data":{"productId":"\u003cstring>","importId":"\u003cstring>","name":"\u003cstring>","internalName":"\u003cstring>","description":"\u003cstring>","seoTitle":"\u003cstring>","seoDescription":"\u003cstring>","seoImageURL":"\u003cstring>","richContent":"\u003cstring>","richContentPosition":"beforeModifiers","hasRichContent":true,"url":"\u003cstring>","partialUrl":"\u003cstring>","categoriesNames":["\u003cstring>"],"categoriesIds":["\u003cstring>"],"modifiersIds":["\u003cstring>"],"externalId":"\u003cstring>","metadata":{},"images":["\u003cstring>"],"menus":[{"menuId":"\u003cstring>","price":123,"discount":123,"available":true,"externalId":"\u003cstring>"}]}}}},"exampleType":"generated"}},"exampleType":"generated"},"a1898574-5870-4a6a-b477-e9e9703156d9":{"description":"Errors","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","example":"false","uniqueKey":"success","typeLabel":"boolean"},"error":{"type":"object","properties":{"error":{"type":"string","example":"error","uniqueKey":"error.error","typeLabel":"string"},"message":{"type":"string","example":"The request has an error","uniqueKey":"error.message","typeLabel":"string"}},"uniqueKey":"error","typeLabel":"object"}},"uniqueKey":"","typeLabel":"object"},"examples":{"Example":{"title":"Example","value":{"success":"false","error":{"error":"error","message":"The request has an error"}}}},"exampleType":"generated"}},"exampleType":"generated"}},"security":{"f943353e-84de-42c1-9797-0c6a5ed8f042":{"Authorization":{"type":"http","scheme":"bearer","description":"Bearer authentication header of the form `Bearer \u003ctoken>`, where `\u003ctoken>` is your auth token."}}},"servers":{"4ae2af61-c215-4cae-8fa3-a789c2e95d34":{"url":"https://api.service.getjusto.com/v3","description":"Production server"}},"processedSecurityOptions":[{"schemes":[{"scheme":{"type":"http","scheme":"bearer","description":"Bearer authentication header of the form `Bearer \u003ctoken>`, where `\u003ctoken>` is your auth token."},"schema":{"title":"Bearer Auth","type":"string","isRequired":true,"description":"Bearer authentication header of the form `Bearer \u003ctoken>`, where `\u003ctoken>` is your auth token.","format":"bearer","typeLabel":"string\u003cbearer>","deprecated":false},"schemeName":"Authorization","name":"Authorization"}],"title":"Authorization"}]},"originalFileLocation":"docs/main/openapi.json"},"subdomain":"justo","siteName":"Justo Docs","title":"Crear producto - Justo Docs","navMaps":{"firstHrefInVersion":{"v3":{"href":"/docs/menu-catalog/endpoints/catalog/create-product","matchLevel":0},"v2":{"href":"/docs/old/v2/legacy-documentation","matchLevel":4}},"firstHrefInLanguage":{}},"lastModified":"2026-10-31T12:42:12.804Z","originalFileLocation":"docs/menu-catalog/endpoints/catalog/create-product.mdx"},"headHtml":"\u003cscript data-mint-head>(function(){var d=document.documentElement,p=null;if(!p){try{p=localStorage.getItem(\"isDarkMode\")}catch(e){}if(p==='true')p='dark';else if(p==='false')p='light';if(p!=='light'\u0026\u0026p!=='dark'\u0026\u0026p!=='system')p=\"system\"}var r=p==='system'?(matchMedia(\"(prefers-color-scheme: dark)\").matches?'dark':'light'):p;d.classList.remove(r==='dark'?'light':'dark');d.classList.add(r);d.setAttribute(\"data-theme-preference\",p)})();\u003c/script>\u003cmeta data-mint-head name=\"description\" content=\"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.\">\u003cmeta data-mint-head name=\"application-name\" content=\"Justo Docs\">\u003cmeta data-mint-head name=\"generator\" content=\"Mintlify\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon/android-chrome-192x192.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"apple-touch-icon\" type=\"image/png\" sizes=\"180x180\" href=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon/apple-touch-icon.png\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon/favicon-16x16.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon/favicon-32x32.png\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon/favicon.ico\" media=\"(prefers-color-scheme: light)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"192x192\" href=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon-dark/android-chrome-192x192.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"16x16\" href=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon-dark/favicon-16x16.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"icon\" type=\"image/png\" sizes=\"32x32\" href=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon-dark/favicon-32x32.png\" media=\"(prefers-color-scheme: dark)\">\u003clink data-mint-head rel=\"shortcut icon\" type=\"image/x-icon\" href=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon-dark/favicon.ico\" media=\"(prefers-color-scheme: dark)\">\u003cmeta data-mint-head property=\"og:title\" content=\"Crear producto - Justo Docs\">\u003cmeta data-mint-head property=\"og:description\" content=\"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.\">\u003cmeta data-mint-head property=\"og:site_name\" content=\"Justo Docs\">\u003cmeta data-mint-head property=\"og:url\" content=\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product\">\u003cmeta data-mint-head property=\"og:type\" content=\"website\">\u003cmeta data-mint-head property=\"og:image\" content=\"https://justo.mintlify.app/_mintlify/api/og/v2?division=Cat%C3%A1logo\u0026amp;title=Crear+producto\u0026amp;description=Crea+un+producto+con+su+precio+y+disponibilidad+en+cada+men%C3%BA.+Requiere+edici%C3%B3n+de+productos+habilitada+en+la+marca.+Las+im%C3%A1genes%2C+SEO+y+contenido+enriquecido+se\u0026amp;theme=d087676ee1e154570081b844\u0026amp;signature=3f361abb84c2f489cc56e2b0d5ede23c7248dac793598b894f5e8101cb78acd6\">\u003cmeta data-mint-head property=\"og:image:width\" content=\"1200\">\u003cmeta data-mint-head property=\"og:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"twitter:card\" content=\"summary_large_image\">\u003cmeta data-mint-head name=\"twitter:title\" content=\"Crear producto - Justo Docs\">\u003cmeta data-mint-head name=\"twitter:description\" content=\"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.\">\u003cmeta data-mint-head name=\"twitter:image\" content=\"https://justo.mintlify.app/_mintlify/api/og/v2?division=Cat%C3%A1logo\u0026amp;title=Crear+producto\u0026amp;description=Crea+un+producto+con+su+precio+y+disponibilidad+en+cada+men%C3%BA.+Requiere+edici%C3%B3n+de+productos+habilitada+en+la+marca.+Las+im%C3%A1genes%2C+SEO+y+contenido+enriquecido+se\u0026amp;theme=d087676ee1e154570081b844\u0026amp;signature=3f361abb84c2f489cc56e2b0d5ede23c7248dac793598b894f5e8101cb78acd6\">\u003cmeta data-mint-head name=\"twitter:image:width\" content=\"1200\">\u003cmeta data-mint-head name=\"twitter:image:height\" content=\"630\">\u003cmeta data-mint-head name=\"msapplication-config\" content=\"/mintlify-assets/_mintlify/favicons/justo/WocLusDjOB_OW0lY/_generated/favicon/browserconfig.xml\">\u003cmeta data-mint-head name=\"apple-mobile-web-app-title\" content=\"Justo Docs\">\u003cmeta data-mint-head name=\"msapplication-TileColor\" content=\"#3b82f6\">\u003clink data-mint-head rel=\"canonical\" href=\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product\">\u003clink data-mint-head rel=\"alternate\" type=\"application/xml\" href=\"/sitemap.xml\">\u003clink data-mint-head rel=\"alternate\" type=\"text/markdown\" href=\"/docs/menu-catalog/endpoints/catalog/create-product.md\">\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@graph\":[{\"@type\":\"Organization\",\"@id\":\"https://docs.getjusto.com/#organization\",\"name\":\"Justo Docs\",\"url\":\"https://docs.getjusto.com\",\"logo\":{\"@type\":\"ImageObject\",\"url\":\"https://mintcdn.com/justo/kGzZskwUmUVkF7RU/logo/logo-dark.svg?fit=max\u0026auto=format\u0026n=kGzZskwUmUVkF7RU\u0026q=85\u0026s=45816fc3a2198f90b32f320e33e24037\"}},{\"@type\":\"WebSite\",\"@id\":\"https://docs.getjusto.com#website\",\"name\":\"Justo Docs\",\"url\":\"https://docs.getjusto.com\",\"publisher\":{\"@id\":\"https://docs.getjusto.com/#organization\"}},{\"@type\":\"WebPage\",\"@id\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product#webpage\",\"url\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product\",\"name\":\"Crear producto\",\"description\":\"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.\",\"dateModified\":\"2026-10-31T12:42:12.804Z\",\"isPartOf\":{\"@id\":\"https://docs.getjusto.com#website\"},\"breadcrumb\":{\"@id\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product#breadcrumb\"}},{\"@type\":\"BreadcrumbList\",\"@id\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product#breadcrumb\",\"itemListElement\":[{\"@type\":\"ListItem\",\"position\":1,\"name\":\"Config\",\"item\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/menu/head-menu\"},{\"@type\":\"ListItem\",\"position\":2,\"name\":\"Catálogo\",\"item\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/list-categories\"},{\"@type\":\"ListItem\",\"position\":3,\"name\":\"Crear producto\",\"item\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product\"}]},{\"@type\":[\"TechArticle\",\"APIReference\"],\"@id\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product#apireference\",\"headline\":\"Crear producto\",\"name\":\"Crear producto\",\"description\":\"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.\",\"url\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product\",\"mainEntityOfPage\":{\"@id\":\"https://docs.getjusto.com/docs/menu-catalog/endpoints/catalog/create-product#webpage\"},\"dateModified\":\"2026-10-31T12:42:12.804Z\",\"publisher\":{\"@id\":\"https://docs.getjusto.com/#organization\"},\"isPartOf\":{\"@id\":\"https://docs.getjusto.com#website\"}}]}\u003c/script>\u003cscript data-mint-head type=\"application/ld+json\">{\"@context\":\"https://schema.org\",\"@type\":\"WebSite\",\"name\":\"Justo Docs\",\"creator\":{\"@type\":\"Organization\",\"name\":\"Mintlify\",\"url\":\"https://mintlify.com\"}}\u003c/script>","siteName":"Justo Docs","nav":{"global":{"anchors":[{"anchor":"Developer Portal","href":"https://developers.getjusto.com","icon":"code"}]},"versions":[{"version":"v3","tabs":[{"tab":"Base","pages":[{"title":"Base","href":"/docs/main/introduction"}]},{"tab":"PDV","pages":[{"title":"PDV","href":"/docs/crisp/endpoints/tabs/get-tab"}]},{"tab":"Ecommerce","pages":[{"title":"Ecommerce","href":"/docs/ecommerce/introduction"}]},{"tab":"Config","groups":[{"group":"Config","pages":[{"group":"Menú","pages":[{"openapi":"head /ecommerce/menu/{menuId}","title":null,"href":"/docs/menu-catalog/endpoints/menu/head-menu"},{"openapi":"get /ecommerce/menu","title":"List menus","href":"/docs/menu-catalog/endpoints/menu/list-menus"},{"openapi":"get /ecommerce/menu/{menuId}","title":"Menu","href":"/docs/menu-catalog/endpoints/menu/get-menu"},{"openapi":"post /ecommerce/menu/{menuId}","title":"Create menu","href":"/docs/menu-catalog/endpoints/menu/create-menu"},{"openapi":"put /ecommerce/menu/{menuId}","title":"Update menu","href":"/docs/menu-catalog/endpoints/menu/update-menu"},{"openapi":"patch /ecommerce/menu/{menuId}","title":"Partially update menu","href":"/docs/menu-catalog/endpoints/menu/partially-update-menu"},{"title":"Crear menú vacío","openapi":"post /ecommerce/menu","href":"/docs/menu-catalog/endpoints/menu/create-empty-menu"},{"title":"Clonar menú","openapi":"post /ecommerce/menu/{menuId}/clone","href":"/docs/menu-catalog/endpoints/menu/clone-menu"},{"title":"Eliminar menú","openapi":"delete /ecommerce/menu/{menuId}","href":"/docs/menu-catalog/endpoints/menu/delete-menu"}]},{"group":"Catálogo","pages":[{"openapi":"get /ecommerce/categories","title":"List categories","href":"/docs/menu-catalog/endpoints/catalog/list-categories"},{"openapi":"get /ecommerce/categories/{categoryId}","title":"Category","href":"/docs/menu-catalog/endpoints/catalog/get-category"},{"title":"Crear categoría","openapi":"post /ecommerce/categories","href":"/docs/menu-catalog/endpoints/catalog/create-category"},{"openapi":"put /ecommerce/categories/{categoryId}","title":"Update category","href":"/docs/menu-catalog/endpoints/catalog/update-category"},{"title":"Eliminar categoría","openapi":"delete /ecommerce/categories/{categoryId}","href":"/docs/menu-catalog/endpoints/catalog/delete-category"},{"openapi":"get /ecommerce/products","title":"List products","href":"/docs/menu-catalog/endpoints/catalog/list-products"},{"openapi":"get /ecommerce/products/{productId}","title":"Product","description":"Devuelve el producto de la marca autorizada, incluyendo seoTitle, seoDescription, seoImageURL, richContent sanitizado y richContentPosition. Los campos SEO son overrides guardados, no metadatos calculados. Un valor null indica generación automática. menus trae el precio y la disponibilidad en cada menú. Acepta ID Justo o externo.","href":"/docs/menu-catalog/endpoints/catalog/get-product"},{"title":"Crear producto","openapi":"post /ecommerce/products","href":"/docs/menu-catalog/endpoints/catalog/create-product"},{"openapi":"put /ecommerce/products/{productId}","title":"Update product","description":"Requiere autorización admin de la marca y edición de productos habilitada. Actualiza sólo los campos enviados, sanitiza el HTML e invalida las cachés de publicación. Devuelve el producto guardado. En MCP, confirma los cambios con el usuario antes de ejecutar update_api_call.","href":"/docs/menu-catalog/endpoints/catalog/update-product"},{"title":"Eliminar producto","openapi":"delete /ecommerce/products/{productId}","href":"/docs/menu-catalog/endpoints/catalog/delete-product"},{"title":"Editar precio de un producto en un menú","openapi":"put /ecommerce/products/{productId}/menus/{menuId}","href":"/docs/menu-catalog/endpoints/catalog/update-product-menu-price"},{"openapi":"get /ecommerce/modifiers","title":"List modifiers","href":"/docs/menu-catalog/endpoints/catalog/list-modifiers"},{"openapi":"get /ecommerce/modifiers/{modifierId}","title":"Modifier","href":"/docs/menu-catalog/endpoints/catalog/get-modifier"},{"openapi":"put /ecommerce/modifiers/{modifierId}","title":"Update modifier","href":"/docs/menu-catalog/endpoints/catalog/update-modifier"},{"openapi":"get /ecommerce/modifier-options","title":"List modifier options","href":"/docs/menu-catalog/endpoints/catalog/list-modifier-options"},{"openapi":"get /ecommerce/modifier-options/{modifierOptionId}","title":"Modifier option","href":"/docs/menu-catalog/endpoints/catalog/get-modifier-option"},{"openapi":"put /ecommerce/modifier-options/{modifierOptionId}","title":"Update modifier option","href":"/docs/menu-catalog/endpoints/catalog/update-modifier-option"},{"openapi":"get /ecommerce/prices","title":"List menus (prices)","href":"/docs/menu-catalog/endpoints/catalog/list-prices"},{"openapi":"get /ecommerce/prices/{priceId}","title":"Menu (price)","href":"/docs/menu-catalog/endpoints/catalog/get-price"},{"openapi":"put /ecommerce/prices/{priceId}","title":"Update menu (price)","href":"/docs/menu-catalog/endpoints/catalog/update-price"},{"title":"Crear grupo de opciones","openapi":"post /ecommerce/modifiers","href":"/docs/menu-catalog/endpoints/catalog/create-modifier"},{"title":"Eliminar grupo de opciones","openapi":"delete /ecommerce/modifiers/{modifierId}","href":"/docs/menu-catalog/endpoints/catalog/delete-modifier"},{"title":"Crear opción","openapi":"post /ecommerce/modifier-options","href":"/docs/menu-catalog/endpoints/catalog/create-modifier-option"},{"title":"Eliminar opción","openapi":"delete /ecommerce/modifier-options/{modifierOptionId}","href":"/docs/menu-catalog/endpoints/catalog/delete-modifier-option"}]},{"group":"Configuración de locales","pages":[{"title":"Consultar configuración del local","openapi":"get /ecommerce/stores/{storeId}/configuration","href":"/docs/menu-catalog/endpoints/store-configuration/get-configuration"},{"title":"Editar información del local","openapi":"put /ecommerce/stores/{storeId}/configuration/details","href":"/docs/menu-catalog/endpoints/store-configuration/update-details"},{"title":"Editar teléfonos del local","openapi":"put /ecommerce/stores/{storeId}/configuration/phones","href":"/docs/menu-catalog/endpoints/store-configuration/update-phones"},{"title":"Editar requisitos de vehículo para despacho","openapi":"put /ecommerce/stores/{storeId}/configuration/delivery-settings","href":"/docs/menu-catalog/endpoints/store-configuration/update-delivery-settings"},{"title":"Editar precios y descuentos de despacho","openapi":"put /ecommerce/stores/{storeId}/configuration/delivery-options","href":"/docs/menu-catalog/endpoints/store-configuration/update-delivery-options"},{"group":"Mesas","pages":[{"title":"Listar sectores y mesas del local","openapi":"get /ecommerce/stores/{storeId}/configuration/tables","href":"/docs/menu-catalog/endpoints/store-configuration/list-tables"},{"title":"Crear una mesa del local","openapi":"post /ecommerce/stores/{storeId}/configuration/tables","href":"/docs/menu-catalog/endpoints/store-configuration/create-table"},{"title":"Editar una mesa del local","openapi":"put /ecommerce/stores/{storeId}/configuration/tables/{tableId}","href":"/docs/menu-catalog/endpoints/store-configuration/update-table"},{"title":"Eliminar una mesa del local","openapi":"delete /ecommerce/stores/{storeId}/configuration/tables/{tableId}","href":"/docs/menu-catalog/endpoints/store-configuration/delete-table"}]},{"group":"Descuentos","pages":[{"title":"Listar descuentos configurables del PDV","openapi":"get /ecommerce/stores/{storeId}/configuration/discount-methods","href":"/docs/menu-catalog/endpoints/store-configuration/list-discount-methods"},{"title":"Crear un descuento del PDV","openapi":"post /ecommerce/stores/{storeId}/configuration/discount-methods","href":"/docs/menu-catalog/endpoints/store-configuration/create-discount-method"},{"title":"Editar un descuento del PDV","openapi":"put /ecommerce/stores/{storeId}/configuration/discount-methods/{discountMethodId}","href":"/docs/menu-catalog/endpoints/store-configuration/update-discount-method"},{"title":"Eliminar un descuento del PDV","openapi":"delete /ecommerce/stores/{storeId}/configuration/discount-methods/{discountMethodId}","href":"/docs/menu-catalog/endpoints/store-configuration/delete-discount-method"}]},{"group":"Medios de pago","pages":[{"title":"Listar medios de pago del PDV","openapi":"get /ecommerce/stores/{storeId}/configuration/payment-methods","href":"/docs/menu-catalog/endpoints/store-configuration/list-payment-methods"},{"title":"Crear un medio de pago manual del PDV","openapi":"post /ecommerce/stores/{storeId}/configuration/payment-methods","href":"/docs/menu-catalog/endpoints/store-configuration/create-payment-method"},{"title":"Editar un medio de pago del PDV","openapi":"put /ecommerce/stores/{storeId}/configuration/payment-methods/{paymentMethodId}","href":"/docs/menu-catalog/endpoints/store-configuration/update-payment-method"},{"title":"Eliminar un medio de pago del PDV","openapi":"delete /ecommerce/stores/{storeId}/configuration/payment-methods/{paymentMethodId}","href":"/docs/menu-catalog/endpoints/store-configuration/delete-payment-method"}]}]}]}]},{"tab":"Delivery","pages":[{"title":"Delivery","href":"/docs/admin/introduction"}]},{"tab":"Royalty","pages":[{"title":"Royalty","href":"/docs/royalty/endpoints/summary"}]},{"tab":"Servicios","pages":[{"title":"Servicios","href":"/docs/services/introduction"}]}]},{"version":"v2","pages":[{"title":"v2","href":"/docs/old/v2/legacy-documentation"}]}]},"basePath":"","title":"Crear producto - Justo Docs","buildId":"dpl_G9nrg4qeJSZtah1Ziwbc2n6WkLch","deploymentId":"dpl_G9nrg4qeJSZtah1Ziwbc2n6WkLch","dynamics":["c2aa737661","2b790eda92","b0f84f53ff","a9bb46feb3"],"chunks":["OpenApiReferenceProvider-B7XKH4J3.js","utils-lOYzL7z-.js","cloneDeep-izs3Hzxb.js","_Uint8Array-BVIqJ90l.js","isObjectLike-C8vmzPEN.js","isArray-Dcu1dQ5t.js","utils-DF6jUUIM.js","toString-BX-iyh8G.js","isSymbol-CSH9U2Gm.js","addUniqueKeysToSchema-Dpsj5f7C.js","snippetPresets-CYeiDe8v.js","style-to-object-BY3JEAdk.js","v4-DIgz8zy6.js","ApiExamples-CUFz1YZ_.js","isEqual-BfaiBbcl.js","usePlaygroundInputsStore-D8H_iLS4.js","shallow-DdluZBHX.js","getApiPlaygroundDisplay-B9922vev.js","CodeSnippet-CMoRNGYs.js","CodeSnippets-DwyrPHuw.js","Page-DSVu9Ucl.js","getPastedJson-G-zIvlHh.js","icon-B03fnEy0.js","MethodPill-CW7teklc.js","DuplicateIcon-CtO8eekd.js","createIcon-DZTKdM_A.js","DynamicMarkdown-D5M2At0B.js","SectionHeading-C_2NaA2U.js","axios-vUo_bRtp.js","Markdown-D7QRHV3m.js","clsx-D1Z-ELXV.js","lib-DuNMoZ05.js","lib-B8HbPgcC.js","html-void-elements-mCSPHezU.js","dist-lvhuD9Du.js","katex-YMM-FMeD.js","marked.esm-CZWythHk.js","AssistantPageLink-CKfC4ywL.js"]}