Versionado y compatibilidad
Cómo se versionan los payloads de webhook, qué significa cada identificador y cada marca de tiempo, y cómo se anuncian los cambios y las obsolescencias
MailLand solo cambia los payloads de webhook de formas que un receptor existente puede ignorar. Esta página expone ese compromiso, los identificadores y marcas de tiempo en los que un receptor puede confiar, y lo que ocurriría antes de introducir cualquier cambio incompatible.
Versión del esquema
Cada tipo de evento tiene una versión de esquema de su payload, un entero positivo. Hoy todos los eventos
están en la versión 1.
- El cuerpo la lleva en
schema_version. - La cabecera
X-MLND-Event-Versionlleva el mismo valor. - Un cuerpo sin
schema_version(enviado antes de que existiera el campo) es de la versión1.
La versión se fija al crear el evento, así que cada reintento del mismo evento lleva la misma versión. El v1
de X-MLND-Signature es la versión del esquema de firma, independiente de ella.
Identificadores
| Identificador | Dónde | Igual entre reintentos | Úselo para |
|---|---|---|---|
event_id | cuerpo, X-MLND-Event-Id | Sí | Deduplicación: procese cada event_id una sola vez |
event | cuerpo, X-MLND-Event | Sí | El tipo de evento, p. ej. message.delivered |
id de adjunto (inbound.received) | cuerpo, data.email.attachments[] | Sí | Reconocer un adjunto que ya descargó; su download_url es nueva en cada intento |
| Id de entrega | X-MLND-Delivery-Id | No, nuevo en cada intento | Soporte y diagnóstico; es el publicId que el historial de entregas muestra para el intento |
X-MLND-Attempt | cabecera | No | Número de intento, desde 1 |
Deduplique por event_id, nunca por el id de entrega. Los eventos pueden llegar más de una vez y
desordenados; para los eventos de mensaje, ordene por data.status_version, que para un mensaje solo crece.
Marcas de tiempo
| Campo | Significado |
|---|---|
occurred_at (cuerpo) | Cuándo ocurrió el propio evento. En los eventos de mensaje es la hora del evento en el servidor de correo, el mismo instante que data.timestamp. |
timestamp (cuerpo) | Cuándo MailLand creó el evento de webhook. Sin cambios respecto a versiones anteriores. |
t en X-MLND-Signature, y X-MLND-Delivery-Timestamp | Cuándo se envió este intento, en segundos Unix. Ambos llevan siempre el mismo valor. |
Todas las horas del cuerpo están en UTC, en ISO 8601 con Z final. El cuerpo es idéntico en cada reintento;
solo cambian las cabeceras de cada intento. La firma cubre t y el cuerpo sin procesar, no las demás
cabeceras: trátelas como metadatos de enrutamiento y confíe en el cuerpo.
Compromiso de compatibilidad
Los receptores deben ignorar los campos JSON y las cabeceras HTTP que no reconozcan. Con esa regla, cada cambio de esta lista es seguro y se hace sin una nueva versión de esquema:
- añadir un campo al cuerpo o a
data, o una cabecera nueva; - añadir un tipo de evento, que solo recibe tras suscribirse;
- añadir un valor a un campo que esta documentación describe como abierto.
Cada cambio de esta otra lista es incompatible y nunca se aplica a una versión existente:
- eliminar o renombrar un campo, una cabecera o un tipo de evento;
- cambiar el tipo, el formato, la unidad o el significado de un campo;
- hacer obligatorio un campo opcional, o anulable un campo no nulo;
- añadir un valor a un campo documentado como lista cerrada.
Un cambio incompatible solo se publicaría como una nueva versión de esquema que usted elige explícitamente. Las suscripciones existentes nunca pasan solas a una versión nueva.
Política de obsolescencia
- Una obsolescencia se anuncia al menos 180 días antes de pedir cualquier migración: en el registro de cambios, en el panel y por correo a los propietarios de la cuenta.
- El aviso indica el evento, la versión o el campo exactos, su sustituto y cómo migrar.
- Un campo obsoleto sigue en el payload y un evento obsoleto sigue disponible para los suscriptores existentes. La obsolescencia por sí sola nunca elimina nada. Retirar una versión exige su propio anuncio, como mínimo 180 días después del aviso de obsolescencia.
Excepciones
inbound.received también usa este sobre. Una diferencia: la download_url de cada adjunto se firma
en cada intento, por lo que cambia entre reintentos; el id del adjunto no.
Los pasos Webhook de las automatizaciones envían un cuerpo plano con los campos del suscriptor, no este
sobre. Desde esta versión añaden event_id, occurred_at y schema_version, y van firmados. Vea abajo.
Pasos Webhook de las automatizaciones
Los pasos Webhook de una automatización se firman igual que los webhooks de cliente: verifique
X-MLND-Signature con el secreto de firma del receptor de ese paso, siguiendo los mismos pasos.
- Cada receptor (una URL de paso distinta) tiene su propio secreto, así que ningún receptor puede generar firmas que otro acepte. Los pasos que envían a la misma URL son un solo receptor y comparten su secreto.
- Lea los secretos con
GET /v1/marketing/automations/{id}/webhook-signing-secrets: una listasecretsde{ webhookUrl, secret }, en el orden de los pasos. Se crean cuando se crea o guarda una automatización con un paso Webhook. Una edición conserva el secreto de cada URL sin cambios; una URL nueva o modificada recibe un secreto nuevo. - Sustitúyalos con
POST /v1/marketing/automations/{id}/webhook-signing-secrets/regenerate, que da a cada receptor un secreto nuevo y los devuelve. Los secretos anteriores dejan de valer al instante, así que antes haga que cada receptor acepte ambos. Una copia de una automatización recibe sus propios secretos, y una automatización a la que se le quitan todos los pasos Webhook los pierde. - Para rotar un solo receptor, envíe
{ "webhookUrl": "<URL del paso>" }como cuerpo de la solicitud regenerate; los demás receptores conservan su secreto. Una URL que no es una URL de paso Webhook de la automatización da400. - Una automatización cuyos receptores aún comparten un secreto se divide en secretos por receptor al activarla o reanudarla, o antes de enviar su siguiente paso Webhook. Nunca se firma una solicitud con un secreto que tiene otro receptor: si la división no es posible, el paso no se envía.
X-MLND-Event-Ides estable para una ejecución de un paso para un suscriptor. Úselo junto con la ventana de 5 minutos sobretpara rechazar repeticiones.- Una automatización guardada antes de que existiera la firma envía solicitudes sin firmar hasta que se guarde de nuevo o se regenere su secreto.
- Estas solicitudes son de mejor esfuerzo: un intento y sin calendario de reintentos. La automatización continúa sea cual sea la respuesta del receptor.