Ir al contenido
Maple

Referencia de la API

El catálogo de tipos de eventos de webhook y la carga útil que lleva cada uno.

Todos los webhooks se entregan en el mismo sobre firmado; solo cambia data según type. Esta página documenta cada tipo de evento. Para firma, entrega, reintentos y reenvío, consulte Webhooks.

Eventos de pedidos

Los webhooks de pedidos son de dos tipos, y distinguirlos es la clave para usarlos bien:

  • order.notification es el evento sobre el que usted cumple el pedido. Le entrega el contenido del pedido para actuar, se dispara una sola vez en el traspaso y su entrega se considera crítica. Construya sobre él su ciclo de aceptar / rechazar / listo / completar.
  • order.created, order.paid y order.cancelled son eventos de ciclo de vida. Cada uno informa un momento de la vida del pedido con datos resumidos, para seguimiento y conciliación. Como order.notification se dispara solo una vez y nunca se actualiza, estos eventos le permiten enterarse de lo que ocurre antes o después de esa instantánea, sobre todo una cancelación o un pago que se liquida más tarde.

Para conocer el orden en que se disparan durante la vida de un pedido, consulte Cuándo se disparan los webhooks.

Tipo Se dispara cuando Suscríbase para… data
order.validation_requested Antes de la notificación: Maple le pide confirmar que el pedido se puede cumplir (solo si usted se suscribe) Validar de antemano la disponibilidad y los precios antes de cobrar al cliente Contenido completo del pedido (misma estructura que order.notification) más validation_id
order.notification El pedido se le entrega para cumplirlo, después de la validación y del control de pago Recibir y cumplir pedidos: el núcleo de una integración Contenido completo del pedido (vea abajo)
order.created Se crea un pedido, antes y con menos detalle que la notificación Reflejar los pedidos nuevos para análisis; detectar pedidos que nunca le llegan (por ejemplo, rechazados en la validación) order_id, location_id, status, total, items, created_at
order.paid El pago se liquida, lo que puede ocurrir después del traspaso (pago en el local, pago mediante enlace) Conciliar el pago sin consultas repetidas order_id, location_id, status, amount, payment_method, payment_source
order.cancelled El cliente o el local cancela, a menudo después de haberle notificado Dejar de preparar un pedido cancelado order_id, location_id, status, reason

¿A qué eventos de pedidos debo suscribirme?

  • Para cumplir pedidos (un POS): order.notification y order.cancelled: reciba los pedidos y deténgase cuando uno se cancele. Agregue order.validation_requested si valida de antemano.
  • Para reportes o conciliación (un OMS, un panel, analítica): también order.created y order.paid, para reflejar el ciclo de vida del pedido y del pago.

La carga útil de order.notification

order.notification (y order.validation_requested) llevan el contenido del pedido en data, suficiente para empezar a cumplirlo. Usa los mismos nombres de campo y montos en centavos enteros que el recurso del pedido, pero es un objeto más pequeño con estas claves (como en cualquier carga útil, ignore las claves que no reconozca):

{
"order_id": "ord_...",
"location_id": "str_...",
"fulfillment_type": "delivery",
"scheduled_for": null,
"delivery_address": {
"street": "123 Main Street",
"unit": "Apt 4B",
"city": "New York",
"state": "NY",
"zip": "10001",
"notes": "Leave at the side door"
},
"customer": { "name": "Alex", "phone": "+14155551234", "phone_last_four": "1234" },
"line_items": [
{
"name": "Latte",
"menu_entity_id": "itm-latte",
"quantity": 1,
"base_price": 450,
"modifiers": [{ "name": "Oat milk", "menu_entity_id": "mod-oat", "quantity": 1, "price": 75 }]
}
],
"totals": { "currency": "USD", "subtotal": 525, "tax": 42, "surcharge": 0, "tip": 0, "delivery_fee": 599, "delivery_tip": 0, "total": 1166 }
}

order.validation_requested lleva el mismo data más un validation_id. Devuélvalo en su POST /v1/orders/{orderId}/validation_result para que el resultado quede vinculado a este intento; un resultado de un intento vencido o anterior se rechaza. Consulte Recibir pedidos.

Este es el contenido del pedido, no su estado actual: no incluye status ni payment. Para el estado actual y autorizado (estado, pago, impuesto por artículo, marcas de tiempo), consulte GET /v1/orders/{orderId}. Los eventos de ciclo de vida llevan únicamente los campos resumidos indicados arriba.

scheduled_for es null en los pedidos para el momento (ASAP). Cuando tiene valor (ISO 8601, UTC), el cliente eligió esa hora de recogida o entrega: la notificación igual llega de inmediato, así que prepare el pedido para scheduled_for, no al recibirlo.

delivery_address es null en los pedidos para recoger y en los pedidos a domicilio sin dirección guardada. Cuando está presente, se incluyen las seis claves; notes contiene las instrucciones de entrega, y unit o notes pueden ser null.

No es un flujo de estados

Maple no emite un webhook por cada cambio de estado. Las transiciones que usted mismo ejecuta (accept, ready, complete) no se le devuelven, y no hay un evento para cuando el pedido llega a IN_DELIVERY ni para cuando el pago pasa a refunded / voided / failed. Consulte el recurso del pedido para conocer el estado actual; vea Ciclo de vida del pedido.

Eventos de reservas

Los eventos de reservas se entregan a cada app activa a la que se le haya otorgado el local, cuyos alcances (scopes) permitidos incluyan bookings:read y cuya suscripción coincida con el tipo de evento. No es necesario que la app sea dueña de la conexión con el POS. El indicador de despliegue de reservas del local debe estar habilitado.

Tipo Cambio informado
booking.created Reserva creada o vista por primera vez desde su proveedor
booking.confirmed Solicitud confirmada
booking.updated Reserva modificada
booking.cancelled Reserva cancelada
booking.declined Solicitud rechazada
booking.seated Grupo sentado
booking.completed Servicio completado
booking.no_show Grupo marcado como ausente (no-show)

Los ocho usan la misma estructura de data. El booking incluido coincide con el recurso GET:

{
"location_id": "str_example",
"previous_status": null,
"booking": {
"object": "booking",
"id": "bkg_example",
"livemode": false,
"created": 1789063200,
"version": 1,
"location_id": "str_example",
"status": "confirmed",
"service_state": null,
"confirmation_code": "AB1234",
"starts_at": "2026-09-12T22:00:00.000Z",
"starts_at_local": "2026-09-12T18:00",
"service_date": "2026-09-12",
"duration_minutes": 90,
"party_size": 2,
"guest": { "first_name": "Alex", "last_name": "Quinn", "phone": "+12125551234", "phone_last_four": "1234", "email": null },
"notes": null,
"channel": "api_partner",
"provider": "maple",
"cancellation_policy": null,
"experience": null,
"updated_at": "2026-09-10T18:01:00.000Z"
}
}

La carga útil es el estado más reciente de la reserva en el primer envío, no una instantánea inmutable de la transición. previous_status es null. Por lo tanto, el nombre de un evento puede describir un cambio anterior al estado actual de la reserva incluida. Una vez registrados para un destinatario, los reintentos conservan esa carga útil y la identidad del evento.

Cada evento original de la bandeja de salida recibe una identidad estable por app y entorno. Dos cambios en la misma reserva siguen siendo distintos aun cuando ambos se envíen con la misma versión de la reserva. Elimine duplicados por ID de evento y concilie por id/version de la reserva; no dependa del orden de entrega. El consumidor independiente para desarrolladores no avanza el cursor de comunicaciones con los invitados. En esta versión no se reenvían eventos del plano de sala; los cambios de la lista de espera tienen sus propios eventos.

Si falla el encolado para un destinatario, no se detiene el encolado para las demás apps o suscripciones elegibles. Los reintentos reutilizan la misma identidad de evento por suscripción. La publicación de eventos de reservas usa como máximo tres intentos de envío, cada uno con reintentos internos acotados. Los eventos internos mal formados y los intentos de envío agotados se conservan para que un operador los investigue, en lugar de bloquear los eventos siguientes o reintentar indefinidamente. Esto es independiente de los reintentos de entrega HTTP de webhooks. Use GET /v1/bookings?updated_since=… para conciliar el estado actual de las reservas después de un hueco en las entregas.

Eventos de lista de espera

Los eventos de lista de espera llegan a las mismas apps que los de reservas: cada app activa a la que se le haya otorgado el local, cuyos alcances permitidos incluyan bookings:read y cuya suscripción coincida con el tipo de evento. Se envían para los locales nativos de Maple mientras el indicador de despliegue de reservas del local esté habilitado. Consulte Administre la lista de espera.

Tipo Cambio informado
waitlist_entry.created Un grupo se unió a la lista de espera
waitlist_entry.notified Maple envió un SMS al grupo avisándole que su mesa está lista
waitlist_entry.seated El grupo se sentó en una reserva de cliente sin reserva (walk-in)
waitlist_entry.removed El grupo se retiró (removed_by_guest) o el establecimiento lo eliminó (removed_by_venue)
waitlist_entry.expired Un grupo notificado no respondió a tiempo

Los cinco usan la misma estructura de data. El waitlist_entry incluido coincide con GET /v1/waitlist_entries/{entryId}:

{
"location_id": "str_example",
"waitlist_entry": {
"object": "waitlist_entry",
"id": "bkw_example",
"livemode": false,
"created": 1789063200,
"location_id": "str_example",
"status": "seated",
"party_size": 2,
"position": null,
"quoted_wait": { "parties_ahead": 1, "wait_minutes": { "min": 15, "max": 30 } },
"joined_at": "2026-09-10T18:00:00.000Z",
"notified_at": "2026-09-10T18:20:00.000Z",
"booking_id": "bkg_example",
"channel": "api_partner",
"guest": { "first_name": "Alex", "last_name": "Quinn", "phone": "+12125551234", "phone_last_four": "1234", "email": null }
}
}

Igual que en los eventos de reservas, la carga útil es el estado más reciente de la entrada en el primer envío: un waitlist_entry.created entregado después de que el grupo se sentó ya muestra seated. Use el tipo de evento para saber qué ocurrió y waitlist_entry.status para saber en qué estado está ahora la entrada. Cada cambio tiene su propio ID de evento por app y entorno; elimine duplicados por ID de evento y no dependa del orden de entrega. Los intentos de entrega, los reintentos y la cuarentena de eventos internos mal formados siguen las reglas de los eventos de reservas descritas arriba. Sentar al grupo también crea una reserva de cliente sin reserva (walk-in), que se informa mediante los eventos de reservas a los que usted se suscriba.

Eventos de local (store)

Estos eventos siguen su acceso a un local: el ciclo de vida de la conexión:

Tipo Cuándo se dispara data (indicativo)
store.provisioned Un comercio otorgó a su app acceso a un local location_id
store.deprovisioned Se revocó un permiso; usted perdió el acceso al local location_id
store.status.changed Cambió su conexión con un local location_id, status (connected / disconnected)

Eventos de menú

Tipo Cuándo se dispara data (indicativo)
menu.sync.completed Se completó una sincronización de menú para un local location_id
menu.sync.failed Falló una sincronización de menú para un local location_id

Consulte Publique un menú.

Evento de prueba

webhook.test se entrega a pedido mediante POST /v1/webhook_subscriptions/{id}/test. Úselo para verificar su controlador antes de recibir tráfico real. La actividad real nunca lo emite.