L
Levely/Desarrolladores

Integración por webhooks

Conecta tu CRM o middleware para enviar cambios de estado de leads a Levely. Levely te entregará la URL completa de tu cliente — configúrala exactamente como te la enviamos.

Webhook de leads

Notifica a Levely cada vez que un lead se crea o cambia de etapa en tu CRM. El endpoint es idempotente: puedes reintentar el mismo evento sin duplicar historial.

Endpoint

POST https://ads-library.levely.digital/api/webhooks/leads/{slug}/{secret}

Levely te asigna un {slug} y un {secret} por cliente. Usa la URL completa tal cual — no modifiques ningún segmento. La autenticación es el secret; no se requieren headers adicionales.

Headers

Content-Type: application/json

Ejemplo con cURL

curl -X POST "https://ads-library.levely.digital/api/webhooks/leads/{slug}/{secret}" \
  -H "Content-Type: application/json" \
  -d '{
    "lead_id": "crm-12345",
    "status": "CREATED",
    "created_at": "2026-06-04T15:30:00Z",
    "utm_source": "facebook",
    "utm_campaign": "verano-2026"
  }'

Payload de ejemplo

{
  "lead_id": "crm-12345",
  "status": "QUALIFIED",
  "created_at": "2026-06-04T15:30:00Z",
  "previous_status": "CONTACTED",
  "raw_crm_status": "Prospecto calificado",
  "utm_source": "facebook",
  "utm_medium": "cpc",
  "utm_campaign": "verano-2026",
  "utm_content": "video-1",
  "utm_term": "keyword",
  "channel": "facebook",
  "platform": "meta",
  "contact_info": { "email": "maria@ejemplo.com", "phone": "+52..." },
  "form_responses": { "presupuesto": "50000" },
  "additional_params": { "vendedor": "ana" }
}
CampoTipoReq.Descripción
lead_idstringIdentificador único del lead en tu CRM. No puede estar vacío.
statusenumEstado normalizado del lead. Valores: CREATED, CONTACTED, QUALIFIED, WON, LOST.
created_atstring | numberNoFecha de creación del lead en tu CRM (ISO 8601 o Unix en segundos/milisegundos). Solo se usa al crear el lead por primera vez.
previous_statusenumNoEstado anterior en tu CRM. Si no lo envías, Levely infiere el estado previo desde su base de datos.
raw_crm_statusstringNoEtiqueta original del CRM antes de mapear al enum de Levely. Se guarda en el historial para auditoría.
utm_source, utm_medium, utm_campaign, utm_content, utm_termstring | nullNoUTMs de atribución. Se guardan en la creación del lead y no se sobrescriben en actualizaciones. Si envías UTMs en eventos posteriores, se actualiza `latest_utms` sin perder los originales.
channelstringNoCanal de adquisición (ej. facebook, google, organic).
platformstringNoPlataforma publicitaria (ej. meta, google).
contact_infoobjectNoDatos de contacto libres (email, teléfono, etc.).
form_responsesobjectNoRespuestas de formulario u otros campos del CRM.
additional_paramsobjectNoCualquier dato adicional que quieras conservar junto al lead.

Estados del funnel

Tu CRM puede usar cualquier nomenclatura interna. Antes de llamar al webhook, mapea cada etapa al enum de Levely:

  • CREATEDLead creado en el CRM
  • CONTACTEDPrimer contacto realizado
  • QUALIFIEDLead calificado / con intención
  • WONVenta cerrada
  • LOSTLead perdido o descartado

Se aceptan saltos de etapa (ej. CREATED → QUALIFIED) y LOST desde cualquier estado. Las transiciones hacia atrás también se registran tal como las envía tu CRM.

Comportamiento del sistema

  • Lead nuevo: si lead_id no existe, se crea el lead y se registra el primer evento de cambio de estado.
  • Cambio de estado: si el lead ya existe y el status es distinto, se actualiza y se agrega un evento al historial.
  • Idempotencia: si envías el mismo lead_id con el mismo status que ya tiene, la respuesta es 200 sin crear eventos duplicados.
  • UTMs: los valores enviados en la creación se conservan como atribución original. En actualizaciones, solo se actualiza latest_utms si incluyes al menos un UTM no nulo.
  • Estado anterior: envía previous_status cuando tu CRM lo conozca. Si no, Levely lo infiere desde su registro.

Respuestas HTTP

CódigoBodyCuándo ocurre
200{ "ok": true }Evento procesado correctamente (incluye reintentos idempotentes).
400{ "error": "Invalid JSON body" }El cuerpo no es JSON válido.
401{ "error": "Invalid webhook secret" }El secret en la URL no existe o es incorrecto.
422{ "error": "lead_id is required" }Falta `lead_id` o está vacío.
422{ "error": "status must be one of: CREATED, ..." }El `status` no pertenece al enum permitido.
422{ "error": "created_at must be ISO 8601 or Unix timestamp" }Se envió `created_at` pero con formato inválido.
500{ "error": "Failed to process lead" }Error interno al persistir el evento.

En integraciones con reintentos automáticos, un 200 con { "ok": true } confirma que el evento fue aceptado. Los errores 4xx no deben reintentarse sin corregir el payload.

¿Necesitas credenciales o ayuda con el mapeo de estados? Contacta al equipo de Levely.