Webhooks

Recibe un aviso cuando una ejecución termine en lugar de hacer sondeos para comprobarlo.

Registra un endpoint una vez y luego pasa su webhook_id cuando inicias una ejecución y te llamamos cuando esa ejecución cambia a un estado al que te suscribiste — normalmente en un minuto.

Registra un endpoint

POST {base_url}/webhooks

{
  "url": "https://hooks.example.com/morphic",
  "events": ["workflow_run.succeeded", "workflow_run.failed"],
  "description": "pipeline de historias"
}

Requiere runs:write. La URL debe ser pública https sin credenciales; una organización tiene hasta 10 endpoints.

La 201 respuesta lleva el id — pásalo como webhook_id en una ejecución — y su secreto de firma (whsec_…), mostrado una sola vez. Guárdalo como guardarías la clave de API.

GET {base_url}/webhooks
DELETE {base_url}/webhooks/{webhook_id}

GET (runs:read) lista tus endpoints, nunca sus secretos. DELETE (runs:write) elimina uno; las entregas que aún estén pendientes para él se descartan. Para rotar un secreto, registra un nuevo endpoint y mueve tus ejecuciones a él.

Eventos

EventoSe activa cuando
workflow_run.succeededla ejecución terminó; sus activos están listos
workflow_run.failedla ejecución se detuvo; error dice por qué
workflow_run.needs_inputla ejecución está esperando a una persona en Morphic Studio
workflow_run.expiredla ejecución nunca terminó dentro de su tiempo de vida

La entrega

POST https://hooks.example.com/morphic
Morphic-Event-Id: 0192f4a0-3c71-7b92-8e14-5d6f2a9b3c07
Morphic-Delivery-Id: 0192f4a0-4d82-7c03-9f25-6e7a3b0c4d18
Morphic-Event-Type: workflow_run.succeeded
Morphic-Signature: t=1790056632,v1=3f9c1a…

{
  "id": "0192f4a0-3c71-7b92-8e14-5d6f2a9b3c07",
  "type": "workflow_run.succeeded",
  "created_at": "2026-09-22T04:17:12Z",
  "api_version": "v1",
  "data": {
    "run": { "id": "0192f3d0-…", "status": "succeeded", "assets": [], "credits_used": 1792 }
  }
}

La ejecución tiene la misma estructura Leer una ejecución de flujo de trabajo devuelve, activos incluido — así que una entrega exitosa no necesita una llamada de seguimiento. Es la ejecución tal como estaba cuando se generó el evento, y los enlaces a sus activos siguen siendo válidos durante aproximadamente un día, mientras duren los reintentos de la entrega.

Verifica cada entrega

Calcula un HMAC-SHA256 de {timestamp}.{raw body} con tu secreto de firma y compáralo con v1 en tiempo constante. Usa el cuerpo sin procesar , antes de cualquier análisis JSON.

import crypto from 'node:crypto';

function verify({ rawBody, header, secret }) {
  const parts = Object.fromEntries(
    header.split(',').map((pair) => pair.split('=')),
  );

  const expected = crypto
    .createHmac('sha256', secret)
    .update(`${parts.t}.${rawBody}`)
    .digest('hex');

  const signed = Buffer.from(expected);
  const given = Buffer.from(parts.v1);

  if (signed.length !== given.length) return false;
  if (!crypto.timingSafeEqual(signed, given)) return false;

  // Rechaza una entrega repetida.
  return Math.abs(Date.now() / 1000 - Number(parts.t)) < 300;
}

Un endpoint de webhook no verificado es una puerta abierta: cualquiera que conozca la URL puede decirte que una ejecución tuvo éxito. Verifica la firma y rechaza una marca de tiempo anterior a cinco minutos.

Reintentos y orden

  • Responde 2xx dentro de 10 segundos. Confirma primero y luego haz el trabajo — un manejador lento se considera un fallo.
  • Un no-2xx o un tiempo de espera se reintenta con retroceso exponencial durante aproximadamente un día y luego se descarta. No se sigue una redirección y cuenta como un fallo.
  • Solo se envían los eventos a los que un endpoint se suscribió; una ejecución que alcanza otro estado no informa nada al respecto.
  • Las entregas pueden llegar desordenadas y más de una vez. Basa la clave en Morphic-Event-Id e ignora una que ya hayas procesado.
  • Una exitosa entrega puede llegar antes de que exista tu propio registro de la ejecución. Gestiona eso en lugar de generar un error — o recurre al sondeo para esas ejecuciones.

Los webhooks son una optimización, no una garantía. Mantén un barrido lento que consulte las ejecuciones de las que no hayas sabido nada, para que un despliegue defectuoso por tu parte no pierda la salida de un día.

En esta página