> ## Documentation Index
> Fetch the complete documentation index at: https://docs.jelou.ai/llms.txt
> Use this file to discover all available pages before exploring further.

# Webhook

> Recibe solicitudes HTTP externas para iniciar o reanudar ejecuciones de tus workflows

El nodo **Webhook** convierte tu workflow en un endpoint HTTP accesible desde cualquier sistema externo. Permite dos flujos principales: **iniciar nuevas ejecuciones** y **reanudar ejecuciones existentes** — todo mediante una simple llamada HTTP.

Piensa en este nodo como la puerta de entrada de tu workflow: sistemas externos tocan la puerta (envían un request HTTP), y tu flujo decide qué hacer con lo que traen.

<Note>
  Solo puede existir **un nodo Webhook por canvas**.
</Note>

***

## URL del webhook

La URL la genera el propio nodo. Ábrelo en Studio y usa **Copiar URL**: el identificador final es el **ID del nodo Webhook**, no un identificador aparte.

Las llamadas entran por el gateway de Jelou. El nodo genera dos URLs, según qué versión del workflow quieras ejecutar.

**Producción** — ejecuta la última versión **publicada** del workflow:

```bash theme={null}
curl -X POST "https://gateway.jelou.ai/workflows/v2/webhooks/skill/{workflowId}/{canal}/{nodeId}" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $JELOU_API_KEY"
```

**Pruebas (draft)** — ejecuta el workflow **tal como está en el canvas ahora**, con los cambios que aún no publicaste:

```bash theme={null}
curl -X POST "https://gateway.jelou.ai/workflows/v2/webhooks/skill/{workflowId}/{canal}/test/{nodeId}" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $JELOU_API_KEY"
```

`{canal}` es el canal del workflow en minúsculas: `whatsapp`, `web`, `instagram`, `facebook`, `slack`, `teams`, `twitter` o `custom`.

<Warning>
  El gateway requiere autenticación. Envía tu API key en el header `x-api-key` en cada llamada al webhook; sin ese header la respuesta es `401 Unauthorized`. Créala y adminístrala en [Claves API](/guides/configuracion/claves-api).
</Warning>

<Info>
  ¿Ya tienes una integración apuntando al host anterior, `workflows.jelou.ai`? **Sigue funcionando** y no necesitas migrarla con urgencia. La URL del gateway aplica a las integraciones nuevas.
</Info>

<Note>
  Copia siempre la URL desde el nodo en lugar de construirla a mano.
</Note>

Los ejemplos de esta página usan la URL de producción. Para probar contra el draft, cambia `{nodeId}` por `test/{nodeId}`.

***

## Modos de operación

El nodo Webhook opera en dos modos, determinados automáticamente por la presencia del `executionId`:

### Iniciar nueva ejecución

Cuando el request **no incluye** un `executionId`, el webhook crea una nueva ejecución del workflow desde cero.

**Caso de uso:** Un sistema externo (CRM, ERP, pasarela de pagos) necesita disparar un proceso automatizado en Jelou.

Para iniciar una ejecución nueva hace falta el identificador del usuario. En el ejemplo va como `?userId=`; la otra forma se explica en [Webhook en Workflows](#webhook-en-workflows).

```bash theme={null}
curl -X POST "https://gateway.jelou.ai/workflows/v2/webhooks/skill/{workflowId}/{canal}/{nodeId}?userId=%2B593999999999" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $JELOU_API_KEY" \
  -d '{"evento": "nuevo_pedido", "cliente": "12345"}'
```

### Reanudar ejecución existente

Cuando el request **incluye** un `executionId`, el webhook reanuda una ejecución que estaba pausada esperando una respuesta externa.

**Caso de uso:** Una pasarela de pagos notifica que el pago fue procesado, y el flujo debe continuar desde donde se detuvo.

```bash theme={null}
curl -X POST https://gateway.jelou.ai/workflows/v2/webhooks/skill/{workflowId}/{canal}/{nodeId} \
  -H "Content-Type: application/json" \
  -H "x-api-key: $JELOU_API_KEY" \
  -d '{"executionId": "abc-123", "status": "paid"}'
```

<Tip>
  El `executionId` puede enviarse en el **body** (usando el path configurado en dot notation) o como **query param** `executionId`. Esto permite usar métodos HTTP como GET que no tienen body.
</Tip>

***

## Configuración

### Nombre de la variable

Define el nombre bajo el cual se almacenarán los datos del webhook dentro de la variable `$webhook`. Los datos recibidos por el request quedarán disponibles en `$webhook.<nombreVariable>`. Por ejemplo, si defines `miWebhook`, podrás acceder al body via `{{$webhook.miWebhook.body}}`, a los headers via `{{$webhook.miWebhook.headers}}`, etc.

### Método HTTP

Selecciona los métodos HTTP que acepta el webhook. Soporta GET, POST, PUT, PATCH y DELETE.

<Warning>
  El método HTTP es **obligatorio**. Si publicas el nodo sin haber seleccionado uno, toda petición a la URL será rechazada. Selecciónalo antes de publicar.
</Warning>

<Note>
  Para métodos sin body (como GET), el `executionId` para reanudar debe enviarse como query param: `?executionId=abc-123`.
</Note>

### Reanudar múltiples veces (oneTimeOnly)

Por defecto, una ejecución puede ser reanudada **más de una vez** por el webhook. Si necesitas restringir esto — por ejemplo, en integraciones de pagos donde una confirmación solo debe procesarse una vez — puedes activar la opción **"Solo reanudar una vez"** en la configuración avanzada.

| Configuración                             | Comportamiento                                                                   |
| :---------------------------------------- | :------------------------------------------------------------------------------- |
| **oneTimeOnly desactivado** (por defecto) | El webhook puede reanudar la misma ejecución múltiples veces                     |
| **oneTimeOnly activado**                  | El webhook solo reanuda la ejecución una vez; intentos posteriores son ignorados |

***

## Variable `$webhook`

Cuando un request llega al nodo Webhook, toda la información del request queda disponible a través de la variable `$webhook`. Funciona de manera similar a `$memory` y `$context`.

| Propiedad                                  | Descripción                      | Ejemplo                                   |
| :----------------------------------------- | :------------------------------- | :---------------------------------------- |
| `$webhook.<nombreVariable>.body`           | Cuerpo del request HTTP          | `{"evento": "pago_exitoso", "monto": 50}` |
| `$webhook.<nombreVariable>.headers`        | Headers enviados en el request   | `{"content-type": "application/json"}`    |
| `$webhook.<nombreVariable>.query`          | Query params de la URL           | `{"ref": "campaign-123"}`                 |
| `$webhook.<nombreVariable>.method`         | Método HTTP utilizado            | `POST`                                    |
| `$webhook.<nombreVariable>.mode`           | Modo de la ejecución             | `new` o `resume`                          |
| `$webhook.<nombreVariable>.executionId`    | ID de la ejecución actual        | `exec-abc-123`                            |
| `$webhook.<nombreVariable>.isNewExecution` | Indica si es una ejecución nueva | `true` o `false`                          |

### Ejemplo de uso en el flujo

Suponiendo que definiste `miWebhook` como nombre de la variable, puedes usar las propiedades en cualquier nodo posterior:

```
# En un nodo Condicional
{{$webhook.miWebhook.body.evento}} == "pago_exitoso"

# En un nodo Texto
El pago de {{$webhook.miWebhook.body.monto}} fue procesado correctamente.

# En un nodo API
Authorization: {{$webhook.miWebhook.headers.authorization}}
```

***

## Webhook en Workflows

El nodo Webhook está disponible en Workflows, lo que permite que flujos conversacionales sean disparados o reanudados por eventos externos.

### Consideraciones para Workflows

<AccordionGroup>
  <Accordion title="Nuevas ejecuciones en Workflows">
    Para iniciar una nueva ejecución de un Workflow vía webhook, el request **debe incluir el identificador del usuario** (por ejemplo, el número de teléfono en WhatsApp). Esto es necesario para que el Workflow pueda enviar mensajes al usuario a través del canal correspondiente.

    Tienes dos formas de enviarlo:

    * **En el body:** configura el campo **ID de usuario** en el panel del nodo con la ruta (dot notation) donde viene el identificador.
    * **Como query param:** agrega `?userId=` a la URL, sin configurar nada en el panel.

    ```bash theme={null}
    # ID en el body, con el campo "ID de usuario" configurado como `phone`
    curl -X POST https://gateway.jelou.ai/workflows/v2/webhooks/skill/{workflowId}/whatsapp/{nodeId} \
      -H "Content-Type: application/json" \
      -H "x-api-key: $JELOU_API_KEY" \
      -d '{"phone": "+593999999999", "evento": "recordatorio"}'

    # ID como query param
    curl -X POST "https://gateway.jelou.ai/workflows/v2/webhooks/skill/{workflowId}/whatsapp/{nodeId}?userId=%2B593999999999" \
      -H "Content-Type: application/json" \
      -H "x-api-key: $JELOU_API_KEY" \
      -d '{"evento": "recordatorio"}'
    ```

    <Note>
      Si no llega el identificador por ninguna de las dos vías, el webhook responde con un error indicando que falta el `userId`.
    </Note>
  </Accordion>

  <Accordion title="Reanudar ejecuciones en Workflows">
    Para reanudar una ejecución existente, solo se necesita el `executionId`. El sistema ya tiene el contexto del usuario desde la ejecución original.
  </Accordion>

  <Accordion title="Restricciones de plataforma">
    En plataformas como WhatsApp, si **no hay una sesión activa** (ventana de 24 horas) entre el usuario y el canal, el webhook no podrá enviar mensajes directamente. En estos casos, puedes usar un **nodo HSM** dentro del flujo para enviar una plantilla aprobada que reabre la ventana conversacional.
  </Accordion>

  <Accordion title="Versionamiento">
    El webhook siempre ejecuta la **última versión publicada** del Workflow. Si hay más de un canal del mismo tipo conectado al proyecto, se utiliza el más reciente.
  </Accordion>

  <Accordion title="Herencia en workflows hijos">
    Cuando un Workflow hijo hereda webhooks de su Workflow padre, si el Workflow hijo recibe un request, este **sobrescribe** los datos del webhook del flujo padre. La data de `$webhook` se propaga a ejecuciones hijas (nodos Workflow internos).
  </Accordion>
</AccordionGroup>

***

## Testing (Draft)

Para probar el webhook durante el desarrollo (antes de publicar), el nodo genera una URL de pruebas que incluye el segmento `/test` antes del ID del nodo:

```bash theme={null}
curl -X POST "https://gateway.jelou.ai/workflows/v2/webhooks/skill/{workflowId}/{canal}/test/{nodeId}" \
  -H "Content-Type: application/json" \
  -H "x-api-key: $JELOU_API_KEY"
```

La URL `/test` ejecuta el draft actual del workflow, así puedes iterar sin afectar la versión publicada. Además, no exige el identificador del usuario: esos parámetros salen del Workflow Tester.

<Warning>
  En Workflows, el testing del draft se realiza a través del **Workflow Tester**. Los parámetros del usuario configurados en el Workflow Tester también aplican cuando se invoca el webhook en modo test.
</Warning>

***

## Retrocompatibilidad

Los webhooks creados antes de esta actualización **siguen funcionando sin cambios**. Las mejoras aplican solo hacia adelante:

* **Webhooks existentes** conservan su configuración legacy, incluyendo el campo "variable" que guardaba la data en `$context`.
* **Webhooks nuevos** siempre guardan la información en la nueva entidad `$webhook`, lo que ofrece una estructura más rica y consistente.
* **Las URLs anteriores siguen atendiendo**, como se indica en [URL del webhook](#url-del-webhook).

<Info>
  Para webhooks legacy que tenían configurada una variable de contexto, el componente de configuración de variable se seguirá mostrando por retrocompatibilidad. En webhooks nuevos, este campo no aparece ya que la data siempre se almacena en `$webhook`.
</Info>

***

## Casos de uso comunes

<CardGroup cols={2}>
  <Card title="Notificaciones de pago" icon="credit-card">
    Recibe confirmaciones de pasarelas como Stripe o MercadoPago y reanuda el flujo de compra.
  </Card>

  <Card title="Integraciones CRM" icon="building">
    Dispara flujos automatizados cuando se crea o actualiza un registro en tu CRM.
  </Card>

  <Card title="Eventos de e-commerce" icon="cart-shopping">
    Procesa eventos como abandono de carrito, envío de pedido o devolución.
  </Card>

  <Card title="Automatizaciones IoT" icon="microchip">
    Recibe datos de sensores o dispositivos para disparar flujos de alerta o procesamiento.
  </Card>
</CardGroup>
