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",
  "entry_channel_crm_enum_id": "939261",
  "channel": "paid",
  "platform": "meta",
  "contact_info": { "email": "maria@ejemplo.com", "phone": "+52..." },
  "form_responses": { "presupuesto": "50000" },
  "additional_params": { "vendedor": "ana" }
}
CampoTipoReq.Descripción
lead_idstringSíIdentificador ú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)Sí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.
statusenumNoEstado canónico del lead (CREATED, CONTACTED, QUALIFIED, WON, LOST). Obligatorio solo si el cliente no tiene mapeo de etapas. Si hay mapeo, Helios ignora este campo y resuelve la etapa desde raw_crm_to_status_id.
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)SíId de etapa CRM después del cambio (Kommo: status_id actual). Con mapeo de etapas es obligatorio: Helios resuelve la etapa Levely desde este id. Sin mapeo, sigue siendo requerido en 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 (Fuente = utm_source). Distinto de Entry Channel (`channel`). 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.
entry_channel_crm_enum_idstring (digits)NoEntry Channel preferido para integraciones CRM (Kommo: enum/option id del campo Tipo de Referral, ej. values[].enum). Se resuelve 1:1 contra el catálogo del cliente (`crm_enum_id`). Si está presente, tiene prioridad sobre `channel` y actualiza el canal del lead aunque el status no cambie. No envíes el label ni el id del custom field.
channelstringNoEntry Channel fallback: slug del catálogo del cliente (ej. paid, organic) o valor raw cubierto por Entry Channel mapping. Se ignora si envías `entry_channel_crm_enum_id`. Distinto de utm_source (Fuente). Valores desconocidos dejan el lead en Sin canal — no crean catálogo.
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. El mapeo de etapas del cliente (admin) traduce el id CRM a la etapa Levely. Sin mapeo, usa los estados canónicos:

  • CREATEDLead creado en el CRM
  • CONTACTEDPrimer contacto realizado
  • QUALIFIEDLead calificado / con intención
  • WONVenta cerrada
  • LOSTLead perdido o descartado
  • Con mapeo de etapas: Helios resuelve la etapa del lead desde raw_crm_to_status_id e ignora el campo status del integrador. Si falta el id CRM, responde 422. Si el id no está mapeado, omite el evento (200 skipped: unmapped_stage), igual que Kommo Sync y Twenty.
  • Sin mapeo de etapas: el webhook acepta status canónico (CREATED, CONTACTED, QUALIFIED, WON, LOST) para escenarios Make existentes. Una identidad extra en status se rechaza hasta que exista mapeo.
  • Lost Motive (lost_motive_id / lost_motive) solo se guarda en transiciones a LOST canónico. Las etapas extra nunca llevan motivo de pérdida.

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).
200{ "ok": true, "skipped": "unmapped_stage" }Hay mapeo de etapas y el id CRM no está mapeado: el evento se omite (igual que Kommo Sync / Twenty). No reintentar.
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, ..." }Sin mapeo de etapas: el `status` no es un valor canónico (CREATED…LOST). Las identidades extra no se aceptan en `status` hasta que exista mapeo.
422{ "error": "raw_crm_to_status_id must be a numeric CRM stage id" }Hay mapeo de etapas y falta raw_crm_to_status_id, o integración Kommo sin id numérico de etapa.
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.