# Flujos de trabajo (/es/concepts/workflows)

Un flujo de trabajo es una automatización modelada como un grafo: los contactos avanzan paso a paso — recibiendo correos, pausando, tomando ramas condicionales, llamando a webhooks, actualizando sus datos, o saliendo. Cada contacto recorre el grafo por su cuenta, en una **ejecución de flujo de trabajo** independiente.

## Disparadores

Cada flujo de trabajo tiene exactamente un **disparador**, que determina cómo entran los contactos:

| Tipo de disparador | Cuándo se dispara                                                                                                                                                                                               |
| ------------------ | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `EVENT`            | Cada vez que un evento coincidente llega a un contacto — un evento personalizado de `/v1/track`, un evento del sistema como `email.received` o `contact.subscribed`, o un evento de entrada/salida de segmento. |
| `MANUAL`           | Nunca por sí solo; solo cuando tú mismo inicias una ejecución mediante `POST /workflows/:id/executions`.                                                                                                        |
| `SCHEDULE`         | Con una cadencia recurrente descrita por `triggerConfig` (por ejemplo, una expresión cron).                                                                                                                     |

Los flujos de trabajo creados a través de la API empiezan por defecto con un disparador `EVENT` que usa el nombre de evento que proporcionaste. Cambiar a `MANUAL` o `SCHEDULE` se hace después, actualizando `triggerType` y `triggerConfig` con `PATCH /workflows/:id`.

Una vez que un flujo de trabajo se ha ejecutado al menos una vez, el nombre de su evento disparador queda **congelado** — elígelo con cuidado. Todo lo demás en la configuración (retrasos de paso, condiciones dentro de un paso) sigue siendo editable.

## Ciclo de vida y el indicador `enabled`

Todo flujo de trabajo nace con `enabled: false`, y **nada se ejecuta hasta que pones `enabled` en `true`**. Si un flujo de trabajo parece no dispararse nunca, revisa primero este indicador — suele ser el culpable habitual.

Si un contacto puede pasar por el mismo flujo de trabajo dos veces lo rige `allowReentry` (desactivado por defecto). Mantenlo desactivado para secuencias de una sola vez, como correos de bienvenida u onboarding; actívalo cuando el journey deba poder repetirse, como recordatorios recurrentes o nuevos avisos.

## Tipos de paso

El primer paso de cualquier flujo de trabajo es un paso `TRIGGER`, creado automáticamente. Todo lo que viene después se construye añadiendo pasos y conectándolos con **transiciones** (los bordes del grafo).

| Tipo de paso     | Propósito                                                                                                                                                     | Configuración requerida                                           |
| ---------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------- | ----------------------------------------------------------------- |
| `TRIGGER`        | El punto de entrada creado automáticamente, con la configuración del disparador.                                                                              | `eventName` (para el disparador `EVENT`)                          |
| `SEND_EMAIL`     | Envía un correo al contacto desde una plantilla; las variables se completan con los datos del contacto más el contexto de ejecución.                          | `templateId`, `from` opcional como override                       |
| `DELAY`          | Mantiene la ejecución en espera un tiempo determinado antes de continuar.                                                                                     | `amount`, `unit` (`minutes` / `hours` / `days`)                   |
| `WAIT_FOR_EVENT` | Mantiene la ejecución en espera hasta que se registre un evento dado en el contacto, y sigue adelante al agotarse el tiempo.                                  | `eventName`, `timeout` (segundos)                                 |
| `CONDITION`      | Divide el camino según los datos del contacto o del evento; todo paso `CONDITION` tiene dos transiciones salientes etiquetadas `yes` / `no`.                  | Una expresión de filtro (misma forma que los filtros de segmento) |
| `WEBHOOK`        | Envía por POST el contexto de contacto y ejecución como JSON a un endpoint HTTPS externo. `{{variables}}` funcionan en `url`, valores de encabezado y `body`. | `url`, `method` opcional, `headers`, `body`                       |
| `UPDATE_CONTACT` | Aplica un parche a los datos del contacto — una forma habitual de marcar progreso (`{ stage: "activated" }`).                                                 | Objeto `data`                                                     |
| `EXIT`           | Termina la ejecución, anotando opcionalmente un `exitReason` para análisis posterior.                                                                         | `reason` opcional                                                 |

## Transiciones

Los bordes que conectan pasos se llaman transiciones. La mayoría de las veces una transición simplemente significa "sigue por aquí"; en los pasos `CONDITION`, cada transición saliente también lleva un valor `branch` (`"yes"` o `"no"`) que indica al motor por dónde continuar una vez evaluada la condición.

¿Quitando un paso de en medio de una cadena? Añade `?splice=true` a `DELETE /workflows/:id/steps/:stepId` y las transiciones vecinas se vuelven a coser automáticamente — sin eso, el grafo queda con un hueco.

## Ejecuciones

Se crea una `WorkflowExecution` para cada contacto que entra. Sus posibles estados:

| Estado      | Significado                                                                                                                         |
| ----------- | ----------------------------------------------------------------------------------------------------------------------------------- |
| `RUNNING`   | Se está procesando un paso, o está a punto de procesarse.                                                                           |
| `WAITING`   | Retenida dentro de un paso `DELAY` o `WAIT_FOR_EVENT`.                                                                              |
| `COMPLETED` | Llegó al final del grafo sin problemas.                                                                                             |
| `EXITED`    | Alcanzó un paso `EXIT`; la causa se guarda en `exitReason`.                                                                         |
| `FAILED`    | Detenida por un error irrecuperable — por ejemplo, un webhook que sigue sin devolver 2xx tras reintentos, o una plantilla faltante. |
| `CANCELLED` | Terminada a mano mediante la API o el panel.                                                                                        |

Cada ejecución tiene su propio objeto JSON `context`. Durante el renderizado de plantillas y la evaluación de condiciones, se fusiona con los `data` del contacto. Los inicios manuales vía `POST /workflows/:id/executions` aceptan un `context` inicial, que es el mecanismo para variables por ejecución — un código de cupón, el nombre de un referente — que no deberían persistirse en el contacto en sí.

## Bloqueo de flujos de trabajo activos

Mientras cualquier ejecución esté activa (`RUNNING` o `WAITING`), el flujo de trabajo queda **bloqueado** frente a cambios estructurales. Antes de hacer un cambio disruptivo — añadir o quitar pasos, cambiar el evento disparador, cambiar el tipo de disparador — haz una de estas dos cosas:

* Desactiva el flujo de trabajo y deja que las ejecuciones en curso terminen, o
* Llama a `POST /workflows/:id/executions/cancel-all` para abortar todo lo que se esté ejecutando en ese momento.

Los cambios no estructurales — renombrar el flujo de trabajo, cambiar el contenido de las plantillas que referencian sus pasos — están permitidos en cualquier momento.

## Patrones habituales

* **Serie de bienvenida** — dispara con el evento `signed_up`, envía el correo de bienvenida, espera 2 días, envía un correo de consejos, espera 5 días más y luego impulsa hacia una actualización de plan.
* **Respuesta automática entrante** — dispara con `email.received`, usa un paso `CONDITION` que comprueba `event.spamVerdict == "PASS"`, y luego `SEND_EMAIL` con la plantilla de respuesta automática. Consulta [Recepción de correos](/es/guides/receiving-emails).
* **Reactivación** — parte de una salida de segmento (`segment.active-users.exit`), envía un mensaje de "te extrañamos", espera hasta 7 días un evento `email.opened`, y luego ramifica según si hubo interacción.
* **Fan-out por webhook** — dispara con `purchase.completed`, llama a tu CRM con un paso `WEBHOOK`, etiqueta al contacto vía `UPDATE_CONTACT` (`{ tier: "customer" }`), y termina con un `SEND_EMAIL` de recibo.

## Referencia de la API

Todo pasa por la API `/workflows`, que cubre el propio flujo de trabajo más sus pasos, transiciones y ejecuciones. La lista completa de rutas está en el [resumen de la API](/es/api-reference/overview#workflows).

## Qué sigue

<Cards>
  <Card title="Plantillas" href="/es/concepts/templates">
    Escribe el contenido de correo que entregan los pasos `SEND_EMAIL`.
  </Card>

  <Card title="Recepción de correos" href="/es/guides/receiving-emails">
    Inicia flujos de trabajo desde correo entrante mediante `email.received`.
  </Card>

  <Card title="Webhooks" href="/es/guides/webhooks">
    Llega a tus propios servicios desde un flujo de trabajo con pasos `WEBHOOK`.
  </Card>

  <Card title="Segmentos" href="/es/concepts/segments">
    Inicia flujos de trabajo desde eventos de entrada/salida de segmento.
  </Card>
</Cards>
