> ## Documentation Index
> Fetch the complete documentation index at: https://firespark.cloud/docs/llms.txt
> Use this file to discover all available pages before exploring further.

# Actualizar producto

> Actualiza un producto dentro de un menú compuesto desde tu POS o RMS.

Actualiza un producto dentro de un menú compuesto. Usa este endpoint cuando tu POS o RMS envía cambios a nivel de ítem — precio, disponibilidad o ítems incluidos en bundle — sin reemplazar el menú completo.

El body usa la misma forma de **producto de menú** que los productos en [Upsert menus](https://firespark.cloud/docs/es/integrations-api/menus/put.md). Envía solo los campos que quieras cambiar; los omitidos conservan su valor actual.

> [!NOTE]
>
> Requiere un access token con el scope `menus:write`. Consulta
> [Token](https://firespark.cloud/docs/es/integrations-api/oauth/token/post.md) para obtener un token.

## Parámetros de ruta

| Parámetro | Descripción |
| - | - |
| `id` | Identificador externo del producto. Solo alfanuméricos, `_` y `-`. 1–64 caracteres. |

## Parámetros de query

| Parámetro | Requerido | Descripción |
| - | - | - |
| `brand_id` | No | Identificador externo de marca. Omite o envía `__ANY__` para el default del comercio. Si se envía, acota el update a menús de esta marca. |
| `store_id` | No | Identificador externo de tienda. Acota el update a menús de esta tienda. Omite o envía `__ANY__` para el default del comercio. |
| `channel_id` | No | Identificador externo de canal. Acota el update a menús de este canal. Omite o envía `__ANY__` para el menú cargado sin canal (`__ANY__`). |
| `fulfillment_id` | No | Identificador externo de fulfillment. Acota el update a menús de ese tipo. Omite o envía `__ANY__` para el menú cargado sin fulfillment (`__ANY__`). Ver [List fulfillment](https://firespark.cloud/docs/es/integrations-api/fulfillment/get.md). |
| `menu_id` | No | Identificador externo de menú. Indica en qué menú buscar el producto cuando varios menús comparten el mismo scope — por ejemplo horarios de almuerzo y cena. El cambio se guarda para el scope, así que aplica a todos los menús de ese scope que contengan el producto. |

Omitir un parámetro de scope **no** significa "todos": se resuelve como `__ANY__` y solo encuentra menús cargados con `__ANY__` en esa dimensión. Si los menús se cargaron por fulfillment o canal (por ejemplo `TAKEAWAY` y `DINE_IN`), envía un update por cada scope; si no hay menú en el scope pedido, la respuesta es `404`. Cada menú compuesto se identifica por `fulfillment_id + store_id + channel_id + brand_id + menu.id`; ver [Menu sync](https://firespark.cloud/docs/es/integrations-api/guides/menu-sync.md#multiple-channels-stores-and-fulfillment-modes).

## Body de la solicitud

Misma forma que un producto en el array `products` de [Upsert menus](https://firespark.cloud/docs/es/integrations-api/menus/put.md). El `id` del producto va en el parámetro de ruta — no lo envíes en el body.

En el update todos los campos son opcionales, incluidos los de `pricing` y `availability`. Los campos omitidos conservan su valor actual y no se aplican valores por defecto:

* `pricing` y `availability` se combinan campo por campo. `{ "pricing": { "price": 2.49 } }` cambia solo el precio; `modifiers`, `modifier_group_ids` y los límites de cantidad no cambian.
* Los arrays (`bundled_items`, `labels`, `pricing.modifiers`, …) se reemplazan completos cuando se envían.
* Para borrar `out_of_stock_until` al volver a `AVAILABLE`, envía `"out_of_stock_until": null`.

> [accordion] products
>
> Cada producto en el cuerpo de la solicitud:
>
> | Campo | Requerido | Tipo | Descripción |
> | - | - | - | - |
> | `id` | Sí | string | Identificador externo del producto. Se envía en el parámetro de ruta — omitir del body. |
> | `name` | Sí | object | Nombre visible localizado por locale (por ejemplo `en_us`). |
> | `description` | No | object \| null | Descripción localizada. `null` si se omite. |
> | `image_url` | No | string | URL de imagen del producto. `null` si se omite. |
> | `bundled_items` | No | array | Ítems incluidos en un bundle o combo. Por defecto `[]`. |
> | `pricing` | Sí | object | Precio, impuestos, límites de cantidad y configuración de modificadores. Ver **pricing**. |
> | `availability` | Sí | object | Disponibilidad del producto. Ver campos abajo. |
> | `labels` | No | string\[] | Etiquetas cortas para filtros y selección rápida en el Dashboard. Como máximo 64 cadenas (1–128 caracteres cada una). Por defecto `[]`. |
> | `tags` | No | object | Tags clave/valor para reglas personalizadas avanzadas. Los valores pueden ser boolean, string o number. Por defecto `{}`. Ver [Reglas personalizadas](https://firespark.cloud/docs/es/integrations-api/guides/custom-rules). |
> | `metadata` | No | object | Metadatos del partner. Por defecto `{}`. |
>
> Cada objeto `availability`:
>
> | Campo | Requerido | Tipo | Descripción |
> | - | - | - | - |
> | `status` | Sí | string | `AVAILABLE`, `HIDDEN` u `OUT_OF_STOCK`. |
> | `schedules` | No | array \| null | Entradas de horario con `day_of_week` y `periods`. `null` cuando no hay restricción de horarios. |
> | `out_of_stock_until` | No | string | Fecha y hora ISO 8601 opcional cuando el producto vuelve a stock. |
>
> Cada entrada de `bundled_items`:
>
> | Campo | Requerido | Tipo | Descripción |
> | - | - | - | - |
> | `id` | Sí | string | Identificador externo del producto incluido. |
> | `refund_price` | Sí | number | Monto de reembolso si el cliente quita este ítem del bundle. ≥ 0. |
> | `included_quantity` | Sí | number | Unidades incluidas por defecto. ≥ 0. |
>
> ```json Ejemplo de producto theme={null}
> {
>   "id": "hamburguesa-clasica",
>   "name": { "en_us": "Hamburguesa clásica" },
>   "description": { "en_us": "Carne Angus con lechuga y tomate." },
>   "image_url": "https://cdn.example.com/hamburguesa-clasica.jpg",
>   "bundled_items": [],
>   "pricing": {
>     "minimum_quantity": 1,
>     "maximum_quantity": 10,
>     "is_tax_inclusive": true,
>     "tax_rate": 0.15,
>     "price": 12.99,
>     "anchor_price": 14.99,
>     "anchor_price_percentage": 0.13,
>     "modifiers": [],
>     "modifier_group_ids": ["elige-bebida"]
>   },
>   "availability": {
>     "status": "AVAILABLE",
>     "schedules": null,
>     "out_of_stock_until": null
>   },
>   "metadata": {}
> }
> ```

> [accordion] pricing
>
> Precio de producto en el cuerpo de la solicitud:
>
> | Campo | Requerido | Tipo | Descripción |
> | - | - | - | - |
> | `minimum_quantity` | No | number | Unidades mínimas por pedido. ≥ 0. Por defecto `0`. |
> | `maximum_quantity` | No | number | Unidades máximas por pedido. 0–1,000,000. Por defecto `1000000`. |
> | `is_tax_inclusive` | Sí | boolean | Si `price` incluye impuestos. |
> | `tax_rate` | Sí | number | Tasa de impuesto como decimal (por ejemplo `0.15` para 15%). 0–1. |
> | `price` | Sí | number | Precio de lista. ≥ 0. |
> | `anchor_price` | No | number | Precio de referencia para tachado o comparación. ≥ 0. |
> | `anchor_price_percentage` | No | number | Descuento mostrado respecto a `anchor_price`. 0–1. |
> | `starting_price` | No | number \| null | Precio "Desde" de referencia. Envía un número para fijarlo o `null` para ocultarlo. Este endpoint guarda el valor tal cual; no lo recalcula. ≥ 0. |
> | `modifiers` | No | array | Overrides de precio y selección por grupo. Por defecto `[]`. |
> | `modifier_group_ids` | No | array | Identificadores externos de grupos de modificadores del producto. Por defecto `[]`. |
> | `variant_group_ids` | No | array | Solo lectura aquí. Los vínculos de variantes los administra la sincronización de menús; este endpoint conserva el valor guardado. Enviar `modifier_group_ids` para un producto con grupos de variantes devuelve `422`. |
> | `variants` | No | array | Solo lectura aquí. Lo administra la sincronización de menús; este endpoint conserva el valor guardado. |
>
> Cada objeto en `modifiers` configura un grupo de modificadores referenciado en `modifier_group_ids`. Acepta los mismos campos de precio que el producto padre, más campos específicos del modificador:
>
> | Campo | Requerido | Tipo | Descripción |
> | - | - | - | - |
> | `modifier_group_id` | Sí | string | Identificador externo del grupo de modificadores. Debe coincidir con un grupo en `modifier_group_ids`. |
> | `minimum_quantity` | No | number | Unidades mínimas por pedido para modificadores de este grupo. ≥ 0. Por defecto `0`. |
> | `maximum_quantity` | No | number | Unidades máximas por pedido para modificadores de este grupo. 0–1,000,000. |
> | `is_tax_inclusive` | Sí | boolean | Si `price` incluye impuestos para modificadores de este grupo. |
> | `tax_rate` | Sí | number | Tasa de impuesto como decimal (por ejemplo `0.15` para 15%). 0–1. |
> | `price` | Sí | number | Precio de lista para modificadores de este grupo. ≥ 0. |
> | `anchor_price` | No | number | Precio de referencia para tachado o comparación. ≥ 0. |
> | `anchor_price_percentage` | No | number | Descuento mostrado respecto a `anchor_price`. 0–1. |
> | `default_quantity` | Sí | number | Cantidad preseleccionada para modificadores de este grupo. ≥ 0. |
> | `charge_above_quantity` | No | number | Selecciones gratuitas antes de cobrar adicionales. Opcional. |
> | `display_type` | No | string | Cómo se muestran los modificadores en la UI: `RADIO`, `CHECKBOX` o `QUANTITY`. Opcional. |
>
> ```json Ejemplo de entrada en modifiers theme={null}
> {
>   "modifier_group_id": "choose-drink",
>   "minimum_quantity": 0,
>   "maximum_quantity": 1,
>   "is_tax_inclusive": true,
>   "tax_rate": 0.15,
>   "price": 0,
>   "anchor_price": 0,
>   "anchor_price_percentage": 0,
>   "default_quantity": 1,
>   "charge_above_quantity": 0,
>   "display_type": "RADIO"
> }
> ```

## Response

Devuelve el producto actualizado en `data` — la misma forma que un producto en [List menus](https://firespark.cloud/docs/es/integrations-api/menus/get.md), incluyendo `id`, `name`, `pricing`, `availability`, `bundled_items` y `metadata`.

## Respuestas de error

| Estado | Descripción |
| - | - |
| `400` | Error de validación. El cuerpo es `{ "error": "Invalid fields", "details": { "<path>": "<message>" } }`. |
| `401` | Access token ausente o inválido. |
| `403` | El token no incluye el scope `menus:write`. |
| `404` | No existe un producto con este `id` en el menú. |


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.