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://helios.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://helios.levely.digital/api/webhooks/leads/{slug}/{secret}" \
  -H "Content-Type: application/json" \
  -d '{
    "lead_id": "12345678",
    "raw_crm_lead_id": "12345678",
    "status": "CONTACTED",
    "raw_crm_from_status_id": "89758063",
    "raw_crm_to_status_id": "89758064",
    "platform": "kommo",
    "created_at": "2026-06-04T15:30:00Z",
    "utm_source": "facebook",
    "utm_campaign": "verano-2026"
  }'

Payload de ejemplo

{
  "lead_id": "12345678",
  "raw_crm_lead_id": "12345678",
  "status": "QUALIFIED",
  "created_at": "2026-06-04T15:30:00Z",
  "previous_status": "CONTACTED",
  "raw_crm_from_status_id": "89758063",
  "raw_crm_to_status_id": "89758064",
  "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. Para Kommo, usa el id numérico del lead (mismo valor que raw_crm_lead_id).
raw_crm_lead_idstring (digits)Id canónico de la entidad lead en el CRM (Kommo: lead.id). Permite reconciliar con Kommo Sync y remapear etapas sin volver a consultar el CRM.
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 Levely anterior. Requerido en cambios de etapa cuando el integrador conoce el estado previo; si no, Levely lo infiere desde su base de datos.
raw_crm_from_status_idstring (digits)NoId de etapa CRM antes del cambio (Kommo: status_id anterior). Requerido en transiciones de etapa para integraciones Kommo; omitir en el primer evento del lead.
raw_crm_to_status_idstring (digits)Id de etapa CRM después del cambio (Kommo: status_id actual). Requerido en cada evento para integraciones Kommo.
raw_crm_statusstringNoObsoleto — usa raw_crm_to_status_id. Si envías solo este campo y es numérico, se acepta como alias de raw_crm_to_status_id.
lost_motive_idstringNoSolo en status LOST: id del motivo de pérdida en el CRM (Kommo: loss_reason_id). Opcional; si falta junto con lost_motive, el portal agrupa en «Sin motivo». Se ignora en otros status.
lost_motivestringNoSolo en status LOST: nombre del motivo de pérdida (Kommo loss reason name). Recomendado enviar junto con lost_motive_id; cualquiera de los dos basta para un bucket con nombre. Se ignora en otros status.
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 y raw_crm_from_status_id cuando tu CRM lo conozca. Si no, Levely lo infiere desde su registro.
  • Kommo / Make: incluye siempre raw_crm_lead_id, raw_crm_to_status_id y, en cambios de etapa, raw_crm_from_status_id con los ids numéricos de Kommo (lead.id y status_id). Usa platform: "kommo" para activar la validación.

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": "raw_crm_to_status_id must be a numeric CRM stage id" }Integración Kommo: falta raw_crm_to_status_id o no es un id numérico.
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.