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

# Publicar un menú

> Envíe el menú completo de un local como un solo documento JSON identificado con sus propios ID estables y luego léalo de vuelta. Publicar es un diff, así que volver a publicar es seguro.

El menú de un local es el catálogo del que los clientes hacen sus pedidos. Usted lo publica como **un solo documento JSON** que describe todo el menú: categorías, artículos, variantes, modificadores y las definiciones de impuestos y cargos que se aplican. Maple se basa en los **ID externos que usted asigna**, de modo que el `menu_entity_id` de cada partida de un pedido se relaciona directamente con su propio catálogo.

Publicar requiere el alcance (scope) `menus:write` y una **conexión activa** con el local. Leer requiere `menus:read`. Consulte [Cómo funciona Maple](/es/developer-api/how-maple-works) para conocer las conexiones.

## La estructura de un menú

Un menú es un árbol con definiciones compartidas a su lado:

```
menu
├── categories[]          (required)
│   └── items[]
│       └── variations[]  (required: at least one — the price lives here)
│           └── modifierGroups[]   (inline, or a reference to a shared group)
├── modifierGroups[]      (shared definitions, referenced by groupId)
├── taxCategories[] / taxRates[]
├── fees[]
└── discounts[] / promotions[] / coupons[]
```

Dos reglas explican la mayor parte del modelo:

* **Todo objeto tiene un `externalId`**: su identificador estable para ese objeto. Usted los elige; Maple nunca los cambia. Volver a publicar con el mismo `externalId` actualiza el mismo objeto. La respuesta también genera ID de Maple (`item_…`, `var_…`, `ctg_…`) como referencia, pero usted direcciona los objetos con su `externalId`.
* **El precio está en la variante.** Incluso un artículo simple tiene al menos una variante (llámela "Regular"). Todos los precios son **enteros en unidades menores**: `450` equivale a \$4.50.

## Un menú mínimo

El documento válido más pequeño es una moneda y una categoría con un artículo que tiene una variante:

```bash theme={null}
curl -X POST $MAPLE_BASE/locations/{locationId}/menu \
  -H "Authorization: Bearer $MAPLE_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "currency": "USD",
    "categories": [
      {
        "externalId": "cat-drinks",
        "name": "Drinks",
        "items": [
          {
            "externalId": "itm-latte",
            "name": "Latte",
            "variations": [
              { "externalId": "var-latte-reg", "name": "Regular", "price": { "amount": { "amountMinor": 450, "currency": "USD" } } }
            ]
          }
        ]
      }
    ]
  }'
```

Una publicación exitosa devuelve el menú resultante con todas las colecciones materializadas y los ID de Maple completados. Los `externalId` que usted envió se devuelven sin cambios.

## Agregue modificadores compartidos

Defina un grupo de modificadores una sola vez en el nivel superior y haga referencia a él con `groupId` donde corresponda, para que "Milk options" quede en un solo lugar en todas las bebidas:

```json theme={null}
{
  "currency": "USD",
  "modifierGroups": [
    {
      "externalId": "grp-milk",
      "name": "Milk",
      "minSelections": 0,
      "maxSelections": 1,
      "options": [
        { "externalId": "mod-whole", "name": "Whole milk" },
        { "externalId": "mod-oat", "name": "Oat milk", "price": { "amount": { "amountMinor": 75, "currency": "USD" } } }
      ]
    }
  ],
  "categories": [
    {
      "externalId": "cat-drinks",
      "name": "Drinks",
      "items": [
        {
          "externalId": "itm-latte",
          "name": "Latte",
          "variations": [{ "externalId": "var-latte-reg", "name": "Regular", "price": { "amount": { "amountMinor": 450, "currency": "USD" } } }],
          "modifierGroups": [{ "groupId": "grp-milk" }]
        }
      ]
    }
  ]
}
```

Una entrada de grupo de modificadores es una **definición en línea** (incluye `name` y `options`) o una **referencia** (`{ "groupId": "grp-milk" }`). No mezcle las dos formas en una misma entrada: un payload que lo haga se rechaza en lugar de truncarse en silencio. Los artículos, las variantes y cada opción pueden incluir grupos de modificadores, lo que le permite anidar opciones donde el menú lo requiera.

<Tip>
  Las categorías y tasas de impuestos, los cargos (como un depósito por botella), los descuentos, las promociones y los
  cupones son colecciones opcionales de nivel superior; cada una se direcciona con su propio `externalId` y se asocia a
  los artículos por ID (`taxCategoryId`, `feeIds`, etc.). La [referencia de endpoints](/es/developer-api/api-reference)
  documenta todos los campos.
</Tip>

## Semántica de la publicación

Cada publicación envía el **menú completo** como su estado deseado. Maple lo compara (diff) con el menú actual (según `externalId`) y aplica el resultado como una versión nueva. De esto se derivan varias reglas:

* **El documento es el menú completo.** Lo que usted envíe se convierte en el menú. Un objeto que publicó antes pero omite en una publicación posterior se **elimina**: para conservarlo, inclúyalo siempre.
* **`stockStatus` es la excepción.** Es un valor a nivel de campo: si lo omite en un objeto que *sí* incluye, se conserva el inventario actual de ese objeto (los objetos nuevos quedan por defecto en `in_stock`). Por eso, marcar un artículo como agotado sigue siendo una publicación completa que incluye todos los objetos; solo cambia un campo.
* **La identidad es su `externalId`.** El mismo `externalId` actualiza el mismo objeto entre publicaciones; uno nuevo crea un objeto nuevo. Use ID que sean estables en su sistema (un SKU o una clave primaria), no nombres para mostrar.
* **Se conserva el orden.** Las categorías, los artículos, las variantes y las opciones aparecen en el orden en que los envía.
* **La validación es todo o nada.** Si algo no es válido, recibe un `400` con todos los problemas y el menú queda exactamente como estaba. Corríjalos todos y vuelva a enviar.
* **Las publicaciones idénticas no hacen nada.** Enviar el mismo documento no cambia nada ni genera movimiento, así que puede publicar con seguridad en cada cambio del menú.
* **Cada cambio genera una versión.** Un cambio de contenido crea una versión nueva; el local siempre sirve la actual.

Como el documento es el estado deseado completo, la integración más simple vuelve a publicar todo el menú cada vez que cambia su fuente. Usted nunca calcula diferencias; Maple lo hace.

### Establezca la zona horaria para la disponibilidad

Las ventanas de disponibilidad (franjas horarias y happy hours) se evalúan en la **zona horaria del menú**. Establézcala con el campo de nivel superior `timezone`, un nombre IANA como `America/New_York`:

```json theme={null}
{ "currency": "USD", "timezone": "America/New_York", "categories": [ /* … */ ] }
```

Si la omite, la zona horaria del menú es **UTC** por defecto, lo que casi nunca es correcto para reglas basadas en el horario. La zona horaria se establece en su **primera** publicación, así que defínala correctamente desde el inicio.

## Léalo de vuelta

```bash theme={null}
curl $MAPLE_BASE/locations/{locationId}/menu \
  -H "Authorization: Bearer $MAPLE_KEY"
```

Devuelve el menú publicado actual: categorías, artículos y variantes con precios, grupos de modificadores compartidos y definiciones de impuestos, cargos y descuentos, y cada objeto devuelve el `externalId` con el que lo publicó. Un local sin menú publicado devuelve un `404`.

## Sepa cuándo se aplica una publicación

Suscríbase a los eventos de sincronización del menú para recibir una notificación a medida que un menú publicado se propaga:

| Evento | Significado |
| - | - |
| `menu.sync.completed` | Terminó la sincronización del menú de un local |
| `menu.sync.failed` | Falló la sincronización del menú de un local |

Consulte [Webhooks](/es/developer-api/concepts/webhooks) para suscribirse y verificarlos.

## Siguiente

<CardGroup cols={2}>
  <Card title="Reciba y decida pedidos" icon="receipt" href="/es/developer-api/guides/receive-orders">
    Las partidas de los pedidos hacen referencia a su menú con el `externalId` que usted asigna.
  </Card>

  <Card title="Esquema completo del menú" icon="code" href="/es/developer-api/api-reference">
    Todos los campos de cada objeto del menú, en la referencia de endpoints.
  </Card>
</CardGroup>


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