Un webhook avisa a una dirección tuya cuando ocurre algo, para que tus sistemas no tengan que consultar la API: cada semana publicada y los cambios del lineal en tus tiendas, en el formato que lee tu sistema. Los webhooks vienen con la API, en el plan Enterprise; la referencia de webhooks recoge cada evento con su contenido.
Añadir una dirección
Un administrador de la cuenta añade cada dirección en la página de su conector, en «Conectores», con su segundo factor, que la página pide antes que nada:
- Elige el formato en «Formato» (en «Webhook», el nuestro, JSON plano o CloudEvents) y de qué avisa la dirección en «De qué avisa»: «Una semana nueva en el portal» viene marcado, y solo aparecen los que se ofrecen a tu cuenta.
- Para el nuestro, JSON plano o CloudEvents, escribe la dirección en «Dirección (https)»:
https://, el puerto estándar, un nombre público (ni una dirección IP ni un nombre interno), sin usuario ni contraseña. No pongas secretos en la dirección: el token que compruebe tu receptor va en la cabecera de autorización opcional (Authorization,X-Api-Key…), que se guarda cifrada y no vuelve a mostrarse. Tealium, Segment, las herramientas de chat y los formatos predefinidos tienen campos propios, en su página (conectores). - Pulsa «Añadir dirección» y copia el secreto de firma (
whsec_…): solo se muestra esta vez.
Una cuenta tiene como máximo 5 direcciones propias. La ficha de cada dirección la nombra solo por su servidor, con si está activa, su última entrega y por qué falló su último mensaje, nunca lo que respondió tu servidor. «Editar avisos y ajustes» cambia de qué avisa y su formato; una clave vacía conserva la guardada. «Enviar una prueba» pone en cola un ping con data vacío. «Quitar», tras confirmarlo, borra la dirección y sus mensajes. Todo cambio queda en la actividad. Cada dirección es del conector desde cuya página la añades, y solo aparece allí.
Los eventos
| Evento | Cuándo se envía |
|---|---|
release.published |
Se publica una semana |
issues.opened |
Las observaciones abren incidencias |
issue.verified |
El siguiente recorrido comprueba incidencias |
order.confirmed |
Una tienda confirma un pedido |
delivery.recorded |
Se registra un albarán |
campaign.response |
Una tienda responde a una campaña |
import.applied |
Se aplica una importación |
import.ended |
Termina una importación |
summary.ready |
Está listo el resumen de una semana |
gap.opened |
Se abre un hueco de distribución en una tienda |
gap.closed |
Se cierra un hueco anunciado |
issue.opened |
Se abre una incidencia de lineal, o se vuelve a abrir |
issue.closed |
Se cierra una incidencia de lineal |
price.changed |
Un precio observado cambia un 5 % o más, y al menos 5 céntimos |
promotion.result |
Se evalúa una tienda y semana de una promoción seguida |
shelf.snapshot |
Se publica la semana de una tienda |
ledger.updated |
Cambian las líneas de tu registro de valor |
Los nueve primeros llevan identificadores, una semana y recuentos: tu sistema lee las filas con su clave de API, las de una importación con catalogue:read (importar por la API); las alertas del resumen están en el portal (alertas y resumen semanal). El release.published de una semana va una vez a cada dirección añadida antes. Los ocho últimos son eventos de datos, con las filas mismas y tus identificadores (ledger.updated, los recuentos y euros de tu registro de valor, sin tienda). El data de cada evento está en la referencia de webhooks.
El mensaje
En nuestro formato cada mensaje es un POST con un cuerpo JSON, { "id", "type", "data", "event_id", "created_at" }: id es el mensaje, el mismo en cada reintento; event_id, el evento, el mismo en todas las direcciones; created_at, cuándo se escribió el mensaje, nunca el momento de un recorrido. Sus cabeceras:
MercaMap-Event-Id: el identificador del mensaje, comoid;MercaMap-Event-Type: el evento, comotype;MercaMap-Signature:t=<seconds>,v1=<hex>, nuestra firma;webhook-id,webhook-timestampywebhook-signature: la firma de Standard Webhooks, cuando el secreto tiene esa forma.
{ "id": "…", "type": "release.published", "data": { "week": "2026-W41", "stores": 12 }, "event_id": "release:2026-W41", "created_at": "2026-10-13T06:05:12.000Z" }
Slack, Microsoft Teams, Google Chat
Los formatos slack, teams y googlechat publican un resumen en un canal o en un espacio. Su dirección es su única clave: se guarda cifrada y no vuelve a mostrarse; la lista solo da la herramienta y el servidor. Slack da un webhook entrante; Teams, el desencadenador «When a Teams webhook request is received» de un flujo de Workflows que cualquiera puede activar, en environment.api.powerplatform.com y con sig=; Google Chat, el webhook entrante de un espacio.
Los mensajes de un evento y una semana forman un resumen, en el idioma de la dirección: un título con cuántos son, la semana, hasta 10 filas (referencia y tienda), «y N más» y un enlace al portal. Nunca llevan shelf.snapshot. Cada dirección recibe como mucho 1 mensaje por segundo, más tarde si su Retry-After lo pide, dentro de 50 bloques en Slack, 28 KB en Teams y 32.000 bytes en Google Chat. En Slack:
{"text":"1 hueco de distribución abierto · Semana 42 de 2026","blocks":[{"type":"header",…},{"type":"section","text":{"type":"mrkdwn","text":"Agua mineral natural 1,5 l · Supermercado Ejemplo Centro (Madrid)"} },…]}
Comprobar la firma
Antes de fiarte de un mensaje:
- Lee
t(segundos Unix) y cadav1deMercaMap-Signature. - Calcula el HMAC-SHA-256 de
t, un punto y el cuerpo tal cual llega, con el secreto de firma completo como clave,whsec_incluido, en hexadecimal. - Compáralo con cada
v1en tiempo constante (basta uno: durante un cambio de secreto hay uno por secreto), y acepta el mensaje solo sitestá a menos de 5 minutos de tu reloj. - Descarta un mensaje cuyo identificador ya hayas tratado.
Un secreto creado o cambiado desde que llegaron estas cabeceras tiene la forma de esa especificación (whsec_ y el base64 de 32 bytes aleatorios), así que sus bibliotecas comprueban el mensaje, con el base64 que sigue a whsec_, descodificado, como clave. La lista dice qué secretos las firman; cambia uno anterior para añadirlas. La referencia de webhooks muestra ambas comprobaciones.
Respuesta, reintentos y desactivación
Responde con cualquier 2xx en cuanto compruebes el mensaje, y trabaja después: esperamos unos segundos y no seguimos redirecciones. Un 410 desactiva la dirección, o borra la suscrita por la API. Un 400, 401, 403, 404, 413 o 422 termina el mensaje como un fallo: se volvería a rechazar. Lo demás (408, 429, 5xx, una redirección, ninguna respuesta) se reintenta hasta 6 veces, desde 5 minutos hasta 1 día, más tarde si tu Retry-After lo pide, nunca más allá.
Tras 20 peticiones fallidas seguidas, la dirección se desactiva («desactivada tras fallos repetidos») y los mensajes que le tocaban entretanto se descartan. Los administradores reciben un correo, y «Conectores» lo muestra. Arregla el receptor, pulsa «Activar» y lee /releases para recuperar las semanas perdidas. «Pausar» la detiene sin correo ni fallo y sin perder sus ajustes; «Activar» la reanuda. Si el equipo de MercaMap la desactiva (cláusula 12.4), desactiva con ella las demás de tu cuenta en su servidor o su nube.
Cambiar el secreto
Si un secreto ha podido filtrarse, pulsa «Cambiar el secreto»: el nuevo se muestra una sola vez y, durante 24 horas, los mensajes llevan un v1 por cada secreto, el nuevo primero, para que tu receptor acepte ambos mientras cambia. Los mensajes en cola se conservan.