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

# Guía de integración

> Conecta servicios externos a Flowker a través de configuraciones de proveedor. Configura la autenticación, mapea campos y ejecuta workflows contra integraciones reales.

Flowker llama a servicios externos (como motores de fraude, procesadores de pago y proveedores de KYC) a través de configuraciones de proveedor. Una configuración de proveedor es tu conexión a una instancia activa de un servicio externo.

En esta guía exploras el catálogo, creas una configuración de proveedor y la referencias desde un nodo de workflow. Después mapeas campos entre tus datos y el servicio, y aprendes cómo Flowker reintenta y protege esas llamadas.

<h2 id="step-1-explore-the-catalog">
  Paso 1: Explora el catálogo
</h2>

***

El catálogo es un registro de solo lectura de los proveedores, los ejecutores del catálogo y los disparadores que vienen con Flowker. Los descubres. Nunca los creas.

<Steps>
  <Step title="Lista los proveedores disponibles">
    Llama al endpoint [Listar proveedores del catálogo](/es/reference/products/flowker/list-catalog-providers) para ver los tipos de servicio a los que se conecta Flowker. El catálogo siempre incluye el conector HTTP genérico. Los proveedores nativos como `ledger` (Midaz) y `tracer` se sintetizan a partir de especificaciones de OpenAPI publicadas y aparecen solo cuando el registro de esquemas nativos está configurado y la síntesis tiene éxito.
  </Step>

  <Step title="Lista los ejecutores del catálogo disponibles">
    Llama al endpoint [Listar ejecutores del catálogo](/es/reference/products/flowker/list-catalog-executors) para ver las operaciones que un nodo de workflow puede invocar. Usa [Listar ejecutores por proveedor](/es/reference/products/flowker/list-executors-by-provider) para acotar la lista a un proveedor.
  </Step>

  <Step title="Lista los disparadores disponibles">
    Llama al endpoint [Listar disparadores del catálogo](/es/reference/products/flowker/list-catalog-triggers) para ver los tipos de disparador integrados: webhooks y programaciones. La API de ejecución de workflow inicia un workflow pero no es un disparador del catálogo.
  </Step>

  <Step title="Elige lo que necesitas">
    Anota el `providerId` y el id del ejecutor del catálogo que corresponden a tu integración. Usas el primero en el [Paso 2](#step-2-create-a-provider-configuration) y el segundo en el [Paso 3](#step-3-reference-the-provider-configuration-from-a-workflow-node).
  </Step>
</Steps>

<Tip>
  Piensa en el catálogo como un menú: muestra lo que Flowker puede llamar. Las configuraciones de proveedor son tus pedidos específicos: la URL base, las credenciales y los ajustes de cada instancia de servicio que usas.
</Tip>

<h2 id="step-2-create-a-provider-configuration">
  Paso 2: Crea una configuración de proveedor
</h2>

***

Llama a [`POST /v1/provider-configurations`](/es/reference/products/flowker/create-provider-configuration) para definir tu conexión a una instancia de un servicio externo.

| Campo                 | Obligatorio    | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| --------------------- | -------------- | ---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`                | Sí             | Un nombre para esta conexión, de 1 a 100 caracteres.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `kind`                | No             | Qué tipo de conexión es esta. Omítelo, o envía `catalog`, para una conexión a un proveedor del catálogo — el caso que cubre esta guía. Envía `external_openapi` para una conexión a un documento de OpenAPI que subiste; consulta [Conectar tu propia API](/es/products/flowker/connecting-your-own-api). Eliges el tipo cuando creas la configuración.                                                                                                                                                                                              |
| `providerId`          | Para `catalog` | El proveedor del catálogo del que esta conexión es una instancia, como `ledger` o `http`. Una configuración de tipo `external_openapi` puede omitirlo, y una lectura de ella devuelve el id reservado `external.openapi`.                                                                                                                                                                                                                                                                                                                            |
| `config`              | Sí             | Los detalles de conexión de esa instancia, como la URL base y las credenciales de autenticación. Flowker valida este mapa contra el JSON Schema del proveedor tomado del catálogo y devuelve `422` cuando no coincide. El secreto dentro del bloque `auth` se guarda en tu backend de secretos, no en el documento de configuración; todo lo demás en el mapa se almacena con la configuración.                                                                                                                                                      |
| `allowedHosts`        | Para `http`    | Los hosts públicos que esta configuración puede llamar. El conector HTTP genérico (`providerId: "http"`) requiere al menos una entrada, y una lista vacía se rechaza con `FLK-0323`. Los proveedores nativos aceptan una lista vacía. Una entrada con un punto inicial coincide con subdominios — `.kyc-provider.io` coincide con `api.kyc-provider.io`. Solo nombres de host: nada de literales de IP, comodines ni puertos. El host de `config.base_url` debe estar cubierto por la lista; de lo contrario, la creación se rechaza con `FLK-0320`. |
| `allowedPrivateHosts` | No             | Hosts privados con nombre que tu equipo de operaciones permite alcanzar a esta configuración. Los metadatos de nube y las direcciones link-local permanecen bloqueados.                                                                                                                                                                                                                                                                                                                                                                              |
| `schemaBindings`      | No             | Los esquemas XSD u OpenAPI vinculados a esta configuración, cada uno con una restricción opcional a operaciones específicas de OpenAPI.                                                                                                                                                                                                                                                                                                                                                                                                              |
| `description`         | No             | Texto libre, hasta 500 caracteres.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                   |
| `metadata`            | No             | Tus propios pares clave-valor.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                       |

<Note>
  Un `providerId` es un identificador del catálogo, y no siempre coincide con el nombre del producto. El catálogo registra Midaz como `ledger`. Toma siempre el valor de [Listar proveedores del catálogo](/es/reference/products/flowker/list-catalog-providers) en lugar de adivinarlo a partir del nombre del producto.
</Note>

<Warning>
  El `providerId` de la configuración y el `executorId` del nodo que la usa deben pertenecer al mismo proveedor del catálogo. El conector HTTP genérico usa `http` para ambos. Flowker rechaza un workflow que empareja una configuración de un proveedor con un ejecutor de otro, con `FLK-0151`.
</Warning>

El ejemplo de abajo construye la conexión que esta guía usa de aquí en adelante: un servicio de puntuación de fraude al que se llega a través del conector HTTP genérico.

<Accordion title="Solicitud de ejemplo">
  ```json theme={null}
  POST /v1/provider-configurations

  {
    "name": "FraudShield Production",
    "description": "Production fraud scoring service",
    "providerId": "http",
    "config": {
      "base_url": "https://api.fraudshield.example.com",
      "auth": {
        "type": "api_key",
        "config": {
          "key": "sk-prod-xxx",
          "header_name": "X-API-Key",
          "location": "header"
        }
      }
    },
    "allowedHosts": ["api.fraudshield.example.com"],
    "metadata": {
      "environment": "production"
    }
  }
  ```

  La respuesta devuelve el `id` de la nueva configuración. Guárdalo. El [Paso 3](#step-3-reference-the-provider-configuration-from-a-workflow-node) y el [Paso 4](#step-4-run-the-workflow) lo ponen en el `providerConfigId` del nodo que llama al servicio.
</Accordion>

<h3 id="authentication">
  Autenticación
</h3>

El bloque `config.auth` contiene la autenticación que requiere el servicio externo, como un par `{ type, config }`. Usa el método que espera tu servicio.

| Tipo                      | Descripción                                                                    | Campos de config                                                                                           |
| ------------------------- | ------------------------------------------------------------------------------ | ---------------------------------------------------------------------------------------------------------- |
| `none`                    | Sin autenticación.                                                             | —                                                                                                          |
| `api_key`                 | API key en header o query.                                                     | `key`, `header_name`, `location`, `query_param_name`, `prefix`                                             |
| `bearer`                  | Token Bearer en el header Authorization.                                       | `token`                                                                                                    |
| `basic`                   | Nombre de usuario y contraseña (Base64).                                       | `username`, `password`                                                                                     |
| `oidc_client_credentials` | Flujo de client credentials de OAuth 2.0 con gestión automática del token.     | `issuer_url`, `client_id`, `client_secret`, `scopes`                                                       |
| `oidc_user`               | Flujo de contraseña del propietario del recurso de OAuth 2.0.                  | `issuer_url`, `client_id`, `username`, `password`, `client_secret`, `scopes`                               |
| `oauth2_token_endpoint`   | Client credentials de OAuth 2.0 contra un token endpoint (sin OIDC discovery). | `token_url`, `client_id`, `client_secret`, `scopes`                                                        |
| `hmac`                    | Firma cada solicitud con un secreto HMAC compartido.                           | `secret`, `algorithm`, `encoding`, `header_name`, `signature_prefix`, `signing_string`, `timestamp_header` |

Flowker almacena las hojas secretas de `config.auth` fuera del documento de configuración persistido. Una lectura autorizada de la configuración de proveedor puede resolver esos valores desde el vault y devolverlos en claro. Las hojas sin resolver permanecen enmascaradas. Otorga el acceso de lectura en consecuencia.

Cualquier otra cosa que coloques en el documento de configuración (un header, por ejemplo) permanece con la configuración, y una lectura puede devolverla. Coloca cada credencial en `config.auth`.

Para rotar un secreto, envía el nuevo valor en una actualización. Para conservar el actual, omite el campo o envíalo vacío. Esto funciona mientras `auth.type` siga siendo el mismo. Una actualización que cambia `auth.type` debe llevar un valor para cada secreto que el nuevo tipo requiere y el anterior no. De lo contrario Flowker la rechaza con `FLK-0952`. Un cambio entre dos tipos que usan el mismo secreto, como de `oidc_user` a `oidc_client_credentials`, no necesita ese valor de nuevo.

<Tip>
  Para integraciones de OAuth 2.0, usa `oidc_client_credentials`. Flowker gestiona la obtención y la renovación del token automáticamente.
</Tip>

<Accordion title="Ejemplo: client credentials de OIDC">
  ```json theme={null}
  {
    "auth": {
      "type": "oidc_client_credentials",
      "config": {
        "issuer_url": "https://auth.fraudshield.com/realms/fraudshield",
        "client_id": "flowker-integration",
        "client_secret": "secret-value",
        "scopes": ["transactions:read", "transactions:score"]
      }
    }
  }
  ```
</Accordion>

### Habilitar y deshabilitar

Las configuraciones de proveedor tienen dos estados: `active` (en uso) y `disabled` (temporalmente fuera de línea). Una nueva configuración de proveedor empieza en estado `active`. Usa [Deshabilitar una configuración de proveedor](/es/reference/products/flowker/disable-provider-configuration) para sacar una conexión de servicio y [Habilitar una configuración de proveedor](/es/reference/products/flowker/enable-provider-configuration) para devolverla.

Consulta la [API de configuraciones de proveedor](/es/reference/products/flowker/list-provider-configurations) para la referencia completa.

<h2 id="step-3-reference-the-provider-configuration-from-a-workflow-node">
  Paso 3: Referencia la configuración de proveedor desde un nodo de workflow
</h2>

***

Cada nodo ejecutor lleva un `providerConfigId`, el identificador de la configuración de proveedor a través de la cual llama. Flowker rechaza un workflow cuyo nodo ejecutor no tiene `providerConfigId`, y rechaza un valor que no es un UUID. En tiempo de ejecución construye cada solicitud saliente a partir de la URL base de esa configuración de proveedor más el path del nodo. El nodo falla si la configuración de proveedor no está `active`.

Estos son los campos que un nodo ejecutor establece en su objeto `data` cuando llama a través del conector HTTP genérico:

| Campo                                              | Obligatorio | Descripción                                                                                                                                                                                                                                                                          |
| -------------------------------------------------- | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `executorId`                                       | Sí          | El ejecutor del catálogo que este nodo invoca, tomado del [Paso 1](#step-1-explore-the-catalog). Flowker rechaza el workflow cuando el id no está en el catálogo. Un nodo que llama a un documento de OpenAPI subido lo omite — ver más abajo.                                       |
| `providerConfigId`                                 | Sí          | El UUID de la configuración de proveedor a través de la cual llama este nodo.                                                                                                                                                                                                        |
| `path`                                             | No          | El path de la solicitud que se anexa a la URL base de la configuración de proveedor. El host de destino es siempre esa URL base — un nodo no puede suministrar una URL absoluta.                                                                                                     |
| `endpointName`                                     | No          | El mismo segmento de solicitud por nombre, usado cuando el nodo no establece `path`. Un nodo que lleva ambos envía `path`.                                                                                                                                                           |
| `method`                                           | No          | `GET`, `POST`, `PUT`, `PATCH`, `DELETE`, `HEAD` u `OPTIONS`. De forma predeterminada es `POST`.                                                                                                                                                                                      |
| `headers`                                          | No          | Headers de la solicitud, fusionados sobre los que define la configuración de proveedor. Un header del nodo gana sobre un header de la configuración de proveedor con el mismo nombre.                                                                                                |
| `query`                                            | No          | Parámetros de query anexados a la URL.                                                                                                                                                                                                                                               |
| `auth`                                             | No          | Un bloque de autenticación `{type, config}` para este nodo, con la misma forma que usa la configuración de proveedor. Cuando está presente tiene precedencia sobre la autenticación de la configuración de proveedor.                                                                |
| `body`                                             | No          | Un cuerpo de solicitud explícito, resuelto contra el contexto del workflow. Cuando se establece, es la única fuente del cuerpo — los mapeos de campos no se le aplican.                                                                                                              |
| `content_digest`                                   | No          | Un pin SHA-256 para el cuerpo de solicitud ensamblado. Establece un digest hexadecimal de 64 caracteres, o un valor resuelto desde el contexto del workflow. Flowker calcula el hash de los bytes finales después de ensamblar el cuerpo y envía la solicitud solo cuando coinciden. |
| `config`                                           | No          | Valores literales fijos que siembran el cuerpo de la solicitud. Consulta [Mapeo de campos y transformación de datos](#field-mapping-and-data-transformation).                                                                                                                        |
| `inputMapping`, `outputMapping`, `transforms`      | No          | Mapeos de campos y transformaciones. Consulta [Mapeo de campos y transformación de datos](#field-mapping-and-data-transformation).                                                                                                                                                   |
| `timeout_seconds`, `retry`, `success_status_codes` | No          | Ajustes de resiliencia por nodo. Consulta [Reintento y circuit breaker](#retry-and-circuit-breaker).                                                                                                                                                                                 |
| `request_format`                                   | No          | Cómo Flowker serializa el cuerpo de la solicitud: `json` (el predeterminado), `xml_converted` o `xml_passthrough`. `xml_converted` también requiere `root_element`.                                                                                                                  |

Un nodo que llama a una operación de un documento de OpenAPI subido la nombra con `operation_path` y `operation_method` en lugar de un `executorId`. Flowker completa el `executorId` por ti a partir de la configuración de proveedor a la que apunta el nodo. [Conectar tu propia API](/es/products/flowker/connecting-your-own-api) recorre todo ese camino.

### Valida la configuración de un nodo antes de guardar

Llama al endpoint [Validar la configuración de un nodo](/es/reference/products/flowker/validate-executor-config) (`POST /v1/catalog/executors/{id}/validate`) para verificar la configuración de un nodo contra el JSON Schema del ejecutor del catálogo.

Esto hace **solo validación de JSON Schema**. Verifica que tu objeto de configuración coincida con la estructura que espera el ejecutor del catálogo (campos obligatorios, tipos, formatos). No llama al servicio externo, así que el primer viaje de ida y vuelta real ocurre cuando un workflow ejecuta el nodo.

Pasa `mappedTargets` para nombrar los campos que tu nodo suministra a través de un `inputMapping` en lugar de un valor fijo. Esos campos cuentan como satisfechos, así que un nodo que mapea un campo obligatorio desde el disparador se valida antes de que lo guardes.

<h2 id="field-mapping-and-data-transformation">
  Mapeo de campos y transformación de datos
</h2>

***

Usa los mapeos de campos y las transformaciones cuando los datos del workflow no coinciden con el formato que espera un servicio externo. Úsalos también cuando un servicio devuelve datos con una forma que el siguiente paso no puede consumir.

Defines los mapeos de campos y las transformaciones dentro del objeto `data` de los nodos ejecutores. Flowker aplica los mapeos de entrada antes de llamar al servicio externo, y los mapeos de salida después de recibir la respuesta.

Un `target` de entrada es una ruta en el cuerpo de la solicitud saliente, escrita exactamente como la espera el servicio externo. No hay objeto envoltorio ni prefijo que agregar. Un `source` de salida es una ruta dentro del envelope de la respuesta, así que los campos de la respuesta quedan bajo `body`.

<Accordion title="Ejemplo rápido: mapear campos del workflow a un nodo ejecutor">
  ```json theme={null}
  {
    "id": "executor-balance",
    "type": "executor",
    "name": "Check Balance",
    "data": {
      "executorId": "http",
      "providerConfigId": "a1b2c3d4-e5f6-4789-a012-345678901234",
      "path": "/accounts/balance",
      "inputMapping": [
        { "source": "workflow.customerId", "target": "accountId" },
        { "source": "workflow.amount", "target": "minimumBalance" }
      ],
      "outputMapping": [
        { "source": "body.currentBalance", "target": "balance" },
        { "source": "body.accountStatus", "target": "status" }
      ]
    }
  }
  ```

  Los nodos downstream leen la salida mapeada bajo el ID de este nodo: `${executor-balance.balance}`.
</Accordion>

Para integraciones complejas, también puedes adjuntar transformaciones a entradas de mapeo individuales (por ejemplo, quitar caracteres, agregar prefijos, cambiar mayúsculas y minúsculas). Puedes definir operaciones de Kazaam para transformaciones avanzadas de JSON a JSON.

[Trabajar con datos de solicitud y respuesta](/es/products/flowker/working-with-request-and-response-data) recorre todo el camino. Cubre cómo declarar los mapeos, cómo elegir qué construye el cuerpo de la solicitud y cómo reestructurar valores en vuelo. También cubre cómo leer la respuesta de vuelta, y cómo verificar la solicitud ensamblada antes de llamar al servicio.

<h2 id="step-4-run-the-workflow">
  Paso 4: Ejecuta el workflow
</h2>

***

Referencia la configuración de proveedor en un nodo de workflow de tipo `executor`.

El ejemplo de abajo crea un workflow de validación de pagos sobre la conexión FraudShield del [Paso 2](#step-2-create-a-provider-configuration). Cuando llega un pago, Flowker llama al servicio de verificación de fraude, evalúa la puntuación de riesgo y aprueba o rechaza el pago según el resultado.

El workflow tiene cinco nodos. Un **disparador** de webhook recibe el pago, y un nodo **ejecutor** llama al servicio de verificación de fraude. Un nodo **condicional** evalúa la puntuación, y hay dos nodos de **acción** para los resultados de aprobación y rechazo. Las aristas los conectan en secuencia, y el nodo condicional se ramifica hacia cualquiera de los dos caminos según el umbral de la puntuación.

Usa el endpoint [Crear workflow](/es/reference/products/flowker/create-workflow) para definir el workflow, luego [Actívalo](/es/reference/products/flowker/activate-workflow) y por último [Ejecútalo](/es/reference/products/flowker/execute-workflow).

<AccordionGroup>
  <Accordion title="Ejemplo: crear un workflow de validación de pagos">
    ```json theme={null}
    POST /v1/workflows

    {
      "name": "payment-validation",
      "description": "Validates a payment before processing.",
      "nodes": [
        {
          "id": "trigger-payment",
          "type": "trigger",
          "name": "Payment received",
          "position": { "x": 0, "y": 0 },
          "data": {
            "triggerType": "webhook",
            "path": "payments/received",
            "method": "POST",
            "input_contract": "open",
            "format": "json"
          }
        },
        {
          "id": "check-fraud",
          "type": "executor",
          "name": "Fraud check",
          "position": { "x": 200, "y": 0 },
          "data": {
            "executorId": "http",
            "providerConfigId": "019c96a0-0ac0-7de9-9f53-9cf842a2ee5a",
            "path": "/score-transaction",
            "method": "POST"
          }
        },
        {
          "id": "evaluate-score",
          "type": "conditional",
          "name": "Score evaluation",
          "position": { "x": 400, "y": 0 },
          "data": {
            "condition": "check-fraud.body.score < 80"
          }
        },
        {
          "id": "approve",
          "type": "action",
          "name": "Approve payment",
          "position": { "x": 600, "y": -100 },
          "data": {
            "actionType": "set_output",
            "output": { "decision": "approved" }
          }
        },
        {
          "id": "reject",
          "type": "action",
          "name": "Reject payment",
          "position": { "x": 600, "y": 100 },
          "data": {
            "actionType": "set_output",
            "output": { "decision": "rejected" }
          }
        }
      ],
      "edges": [
        { "id": "e1", "source": "trigger-payment", "target": "check-fraud" },
        { "id": "e2", "source": "check-fraud", "target": "evaluate-score" },
        { "id": "e3", "source": "evaluate-score", "target": "approve", "sourceHandle": "true" },
        { "id": "e4", "source": "evaluate-score", "target": "reject", "sourceHandle": "false" }
      ]
    }
    ```

    El nodo `check-fraud` nombra `http`, el conector HTTP genérico del catálogo. También nombra la configuración FraudShield del Paso 2, que contiene la URL base y las credenciales. Ambos lados nombran al mismo proveedor, así que el workflow se guarda. Flowker envía la solicitud a `https://api.fraudshield.example.com/score-transaction`.

    El nodo no declara `outputMapping`, así que su salida conserva la forma del envelope de la respuesta. Por eso la puntuación queda en `check-fraud.body.score`, que es lo que lee la condición `evaluate-score`. Agrega un `outputMapping` cuando prefieras un nombre más plano. Consulta [Mapeo de campos y transformación de datos](#field-mapping-and-data-transformation).
  </Accordion>

  <Accordion title="Ejemplo: ejecutar el workflow">
    ```json theme={null}
    POST /v1/workflows/{workflowId}/executions
    Idempotency-Key: {unique-uuid}

    {
      "inputData": {
        "transactionId": "txn-98765",
        "amount": 1500.00,
        "currency": "BRL",
        "customerId": "cust-12345"
      }
    }
    ```
  </Accordion>
</AccordionGroup>

## Disparar workflows

***

Disparas las ejecuciones de workflow mediante el endpoint [Ejecutar workflow](/es/reference/products/flowker/execute-workflow):

```
POST /v1/workflows/:workflowId/executions
```

El cuerpo de la solicitud contiene el `inputData` de la ejecución. Todos los campos están disponibles para los nodos siguientes mediante el namespace `workflow` (por ejemplo, `workflow.transactionId` o `workflow.amount`). Las salidas de los nodos están disponibles mediante el ID del nodo (por ejemplo, `check-fraud.body.score` para un nodo que no declara `outputMapping`).

### Idempotencia

Cada solicitud de ejecución debe incluir un header `Idempotency-Key`. Una solicitud sin él falla con `400 Bad Request` (error `FLK-0509`). Genera un UUID nuevo para cada ejecución nueva, y reutiliza la misma clave solo cuando reintentas la solicitud idéntica.

## Disparadores de webhook

***

Los webhooks son la vía principal por la que los sistemas externos disparan workflows de Flowker. En lugar de que tu sistema llame a la API de ejecuciones directamente, registras un path de webhook en un workflow. Los servicios externos envían entonces solicitudes HTTP a ese path.

### Cómo funciona

1. Agrega a tu workflow un nodo disparador de tipo `webhook` con un `path` y un `method` en su `data`. Establece `input_contract` de forma explícita en los nodos nuevos cuando necesites validación `open`, `xsd` o `openapi`.
2. Cuando activas el workflow, Flowker registra el path en su registro de webhooks.
3. Los sistemas externos envían solicitudes a [`POST /v1/webhooks/{path}`](/es/reference/products/flowker/trigger-webhook) (o el método que configuraste).
4. Flowker resuelve el path al workflow correspondiente y lo ejecuta.

### Definir un nodo disparador de webhook

El disparador de webhook es un nodo con `type: "trigger"` y `triggerType: "webhook"` en su `data`, más un `path`, un `method` y un `input_contract` opcional. [Configurar un disparador de webhook](/es/products/flowker/configuring-a-webhook-trigger) cubre cada campo, los tres modos de `input_contract` y lo que requiere cada uno, y lleva un nodo resuelto para cada modo.

La configuración del disparador sigue un contrato cerrado. Guardar un workflow falla con `FLK-0934` cuando su disparador de webhook omite `path` o `method`, o le falta un campo que requiere el modo de `input_contract` seleccionado. También falla cuando el disparador nombra el id de esquema o el campo de operación de otro modo. Falla también cuando el disparador lleva una clave o un valor que el esquema no acepta. Una declaración de `accepted_headers` inválida falla en cambio con `FLK-0957`.

El esquema también declara los campos opcionales `response_mode`, `response_view` y `accepted_headers`. Consulta [Configurar un disparador de webhook](/es/products/flowker/configuring-a-webhook-trigger).

<h3 id="securing-a-webhook">
  Asegurar un webhook
</h3>

La entrega de webhooks usa la misma autenticación que el resto de la API. Con Access Manager habilitado (`PLUGIN_AUTH_ENABLED=true`), cada solicitud a `/v1/webhooks/*` debe llevar un token Bearer (JWT de OIDC), y quien llama debe tener el permiso `execute` sobre el recurso `webhooks`. Una solicitud sin un token válido falla con `401 Unauthorized`.

Otorga ese permiso a una identidad máquina a máquina para cada sistema al que dejas llamar a tus webhooks, y gestiona la concesión en Access Manager. Esto mantiene el acceso a los webhooks bajo el mismo modelo de roles y políticas que la gestión de workflows, en lugar de una credencial adjunta al path.

<h3 id="webhook-metadata">
  Metadatos del webhook
</h3>

Flowker inyecta automáticamente un objeto `_webhook` en el `inputData` de la ejecución con metadatos sobre la solicitud entrante:

| Campo                | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                  |
| -------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `_webhook.method`    | Método HTTP usado (por ejemplo, `POST`).                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                     |
| `_webhook.path`      | El path de webhook resuelto.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |
| `_webhook.headers`   | Headers de la solicitud, filtrados por una lista de permitidos segura (`Content-Type`, `Accept`, `User-Agent`, `X-Request-Id`, `X-Forwarded-For`, `Idempotency-Key`) más los `accepted_headers` opcionales de este disparador y, para una ruta `openapi`, los parámetros de header de su operación. La lista de bloqueo fija bloquea `Authorization`, `Proxy-Authorization`, `Cookie`, `Set-Cookie`, `X-API-Key` y `X-Auth-Token`. Los demás headers admitidos se persisten tal cual; nunca admitas nombres que lleven secretos como `X-Amz-Security-Token`. |
| `_webhook.query`     | Conserva los nombres de los parámetros de query recibidos. Conserva los valores solo para `customerId`, `page`, `cursor`, `limit`, `offset` y `sortOrder` (sin distinguir mayúsculas y minúsculas); todos los demás valores se almacenan como `[redacted]`.                                                                                                                                                                                                                                                                                                  |
| `_webhook.remote_ip` | Dirección IP de quien llama.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                 |

Estos metadatos están disponibles para todos los nodos del workflow mediante el namespace `workflow._webhook`.

### Notas importantes

* Solo un workflow activo puede registrar cada combinación de path + método de webhook. Activar un segundo workflow con el mismo path falla con un error de conflicto.
* Los paths de webhook admiten segmentos anidados (por ejemplo, `payments/stripe/received`).
* El tamaño máximo del cuerpo de la solicitud es 1 MB.
* Desactivar un workflow da de baja automáticamente sus rutas de webhook.

Consulta la referencia de API [Disparar un webhook](/es/reference/products/flowker/trigger-webhook) para la documentación completa del endpoint.

<h3 id="synchronous-response-mode">
  Modo de respuesta síncrono
</h3>

De forma predeterminada, un disparador de webhook responde con un comprobante `202` en cuanto la ejecución empieza (el modo asíncrono). Quien llama debe consultar el estado de la ejecución por separado. Establece `response_mode` en `"sync"` en el `data` del nodo disparador para que Flowker mantenga abierta la conexión HTTP y devuelva el resultado de la ejecución directamente en la respuesta:

| Campo           | Tipo   | Obligatorio | Descripción                                                                                                                                                                                                                           |
| --------------- | ------ | ----------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `response_mode` | string | No          | `"async"` (predeterminado) devuelve un comprobante `202` de inmediato. `"sync"` se bloquea (hasta un límite interno) a la espera de que la ejecución alcance un estado terminal y devuelve el resultado en el cuerpo de la respuesta. |
| `response_view` | string | No          | Da forma al cuerpo de la respuesta síncrona. Solo tiene sentido cuando `response_mode` es `"sync"`. Consulta la tabla de abajo. De forma predeterminada es `"full"`.                                                                  |

Si la ejecución no alcanza un estado terminal antes de que transcurra el límite interno de espera, Flowker recurre al comprobante `202` del modo asíncrono. Ese comprobante lleva un header `Location` que apunta al endpoint de resultados.

`response_view` selecciona la forma del cuerpo de la respuesta síncrona:

| Valor                   | Descripción                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                          |
| ----------------------- | -------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `full` (predeterminado) | El volcado completo de la ejecución — `executionId`, `workflowId`, `status`, `stepResults`, `finalOutput` — la misma forma que obtendrías del endpoint de resultados de la ejecución.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                |
| `final_output`          | Solo el mapa `finalOutput` de la ejecución, sin envoltorio de envelope.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                              |
| `receipt`               | El comprobante de ejecución reducido (`executionId`, `workflowId`, `status`, `startedAt`) — la misma forma que devuelve el camino asíncrono.                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                         |
| `passthrough`           | Da forma a la respuesta según el **tipo de nodo del paso terminal (el último ejecutado)**. Para un ejecutor terminal que capturó una respuesta del proveedor, devuelve el estado del proveedor (incluido `4xx`) y el `Content-Type`. Retransmite como máximo 8 KiB del cuerpo capturado; los cuerpos más largos se truncan. Los cuerpos JSON se decodifican y se vuelven a serializar antes de la captura, así que la retransmisión byte a byte no está garantizada. Si el paso terminal es una acción `set_output` con una salida configurada, la respuesta es la salida de negocio de ese nodo, respetando su anulación `responseStatusCode`. Si no aplica ninguno de los dos casos (sin respuesta del proveedor capturada — circuito abierto, timeout, falla previa al despacho — y sin salida terminal), recurre al envelope completo en HTTP `200` para que quien llama igual obtenga un resultado con sentido. |

El `finalOutput` de una ejecución fallida (en la vista `full` o `final_output`) siempre lleva `status: "failed"` y `errorMessage`, y `errorClass` cuando Flowker pudo clasificar la falla, nunca un `{}` vacío. Sin una anulación `responseStatusCode` (ver más abajo), el estado HTTP síncrono se mantiene en `200` para `full`/`final_output`/`receipt` (reporta la salud del transporte, no el resultado de negocio). Un `responseStatusCode` válido en el nodo `set_output` terminal anula ese estado para esas tres vistas.

Un nodo de acción con `actionType: "set_output"` puede llevar un `responseStatusCode` opcional (entero, `200`–`599`) para anular el estado HTTP que devuelve una respuesta de webhook `sync`. Un valor fuera de rango o que no es entero falla al guardar (`FLK-0122`). Para `passthrough`, la anulación aplica solo cuando el propio nodo `set_output` es el paso terminal. El estado del proveedor retransmitido por un ejecutor terminal siempre gana, y el respaldo sin respuesta siempre usa un `200` simple para que una anulación nunca enmascare una falla.

La detección de passthrough es estricta: solo cuenta el paso terminal. Un `set_output` terminal downstream de un ejecutor da forma a la respuesta como su propia salida. Flowker nunca retrocede a la respuesta de un ejecutor anterior. En una ejecución fallida el paso que detiene es el paso terminal, así que Flowker retransmite un `4xx` del proveedor que detuvo el workflow como el `4xx` real.

Los valores de la salida de un nodo `set_output` admiten referencias `${...}` resueltas contra el contexto del workflow, incluidas `${workflow.<field>}` (payload del disparador), `${execution.id}`, `${execution.startedAt}` y `${execution.now}` (sellado en el momento de la interpolación). Una referencia `${...}` que no se puede resolver hace fallar el paso (fail-closed).

## Tratamiento de errores

***

Si un nodo falla, la ejecución se detiene y su estado pasa a `failed`.

No hay respaldo automático. Después de que se agotan los reintentos, la ejecución falla.

Los resultados de la ejecución reportan el `status` de la ejecución y los `stepResults`. Un paso fallido proporciona `stepNumber`, `nodeId`, `status` y `errorMessage`, con `statusCode` y `errorClass` cuando están disponibles. El campo `output` es opcional. No prometas un `errorCode`, incluidos `FLK-0504` o `FLK-0507`, en cada payload de resultados de ejecución.

<h2 id="retry-and-circuit-breaker">
  Reintento y circuit breaker
</h2>

***

Flowker incluye resiliencia integrada para las llamadas de ejecutor.

### Reintentos

Cuando una llamada de ejecutor falla con un error transitorio (un error de red, un timeout en el intento, cualquier estado `5xx`, o el estado `408` o `429`), Flowker reintenta automáticamente. El comportamiento de reintento se configura por nodo, en el `data` del nodo ejecutor:

| Ajuste                  | Predeterminado                             | Límites                       | Descripción                                                                                                                    |
| ----------------------- | ------------------------------------------ | ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------ |
| `timeout_seconds`       | 30                                         | 1–300                         | Timeout por solicitud.                                                                                                         |
| `retry.max_attempts`    | 3 (1 para `POST` y `PATCH` sin configurar) | 1–10 aceptados; 1–5 efectivos | Acepta `1`–`10` en el esquema del nodo, pero Flowker limita la cantidad efectiva de intentos en tiempo de ejecución a `1`–`5`. |
| `retry.backoff_seconds` | 1                                          | 1–60                          | Primer techo de backoff; cada espera es un valor aleatorio entre cero y el techo, que se duplica por intento.                  |
| `success_status_codes`  | `[200, 201, 202, 204]`                     | 100–599                       | Códigos de estado HTTP tratados como éxito.                                                                                    |

Los reintentos aplican solo cuando la operación es segura de repetir. De forma predeterminada, Flowker trata las llamadas `POST` y `PATCH` como no idempotentes y **no** las reintenta (un solo intento), mientras que `GET`, `PUT`, `DELETE` y los demás verbos reintentan con normalidad. Un `retry.max_attempts` mayor que `1` activa los reintentos en ese nodo sea cual sea el método. Un `retry.max_attempts` de `1` no es una activación. Establece un solo intento.

**Los errores no reintentables** cortocircuitan a un solo intento sin importar la configuración. Son: circuit breaker abierto, contexto cancelado, errores de configuración y fallas de resolución de secretos. También incluyen un cuerpo de solicitud que supera el límite de tamaño configurado, un cuerpo de respuesta del proveedor que supera ese mismo límite y respuestas `4xx` no transitorias del proveedor. Eso significa cualquier `4xx` salvo `408` y `429`.

El reintento aplica por ejecución de nodo. Si todos los intentos fallan, el paso falla y la ejecución se detiene.

### Circuit breaker

Flowker usa un circuit breaker para que las llamadas fallidas repetidas no saturen los servicios externos:

| Parámetro                | Valor                                                                    |
| ------------------------ | ------------------------------------------------------------------------ |
| Umbral de fallas         | 20 fallas consecutivas abren el circuito (configurable en el despliegue) |
| Timeout de recuperación  | 30 segundos antes de volver a intentar (estado half-open)                |
| Solicitudes en half-open | 1 solicitud permitida para probar si el servicio se recuperó             |

Los errores `4xx` de cliente o de autenticación del proveedor **no** disparan el circuito: son el problema de quien llama, no una señal de que el proveedor está caído. Solo las fallas de nivel de transporte y las `5xx` cuentan para el umbral.

Cuando el circuito está abierto, las llamadas de ejecutor fallan de inmediato con `FLK-0507` en lugar de llegar al servicio externo. Esto evita las fallas en cascada y da tiempo al servicio externo para recuperarse.

<Frame caption="Transiciones de estado del circuit breaker">
  <img src="https://mintcdn.com/lerian-49cb71fc/RAVxFNT8MNA4GWjO/images/es/d2/flowker-circuit-breaker.svg?fit=max&auto=format&n=RAVxFNT8MNA4GWjO&q=85&s=1a723e087e75baa3f00cdc077dd3bee3" alt="Estados del circuit breaker" width="1152" height="394" data-path="images/es/d2/flowker-circuit-breaker.svg" />
</Frame>

El circuito empieza en el estado **Closed**, donde todas las solicitudes pasan con normalidad. Después de que el circuito alcanza el umbral de fallas, transita a **Open** y bloquea todas las solicitudes de inmediato. Después de 30 segundos, pasa a **Half-Open** y permite una solicitud de prueba. Si esa solicitud tiene éxito, el circuito vuelve a Closed. Si falla, el circuito se vuelve a abrir por otro ciclo de 30 segundos.

<Warning>
  El circuit breaker opera por configuración de proveedor, acotado a tu tenant. Las fallas contra una conexión no afectan a otra, y un tenant no puede abrir el circuito de otro. Los umbrales del circuit breaker (cantidad de fallas, timeout de recuperación) son valores predeterminados globales del despliegue. No puedes personalizarlos por conexión en esta versión.
</Warning>

## Registro de configuraciones de ejecutor

***

Este registro es un tercer uso, separado, de la palabra "executor". Sus entradas no son los ejecutores del catálogo del [Paso 1](#step-1-explore-the-catalog). No son los nodos de workflow de `type: "executor"`, ni las configuraciones de proveedor del [Paso 2](#step-2-create-a-provider-configuration). El motor lee las configuraciones de proveedor para llamar a servicios externos, no estas entradas, y el registro lleva su propio vocabulario de campos (`baseUrl`, `endpoints`, `authentication`). El registro expone cuatro operaciones:

| Operación  | Endpoint                                                                                    |
| ---------- | ------------------------------------------------------------------------------------------- |
| Listar     | [`GET /v1/executors`](/es/reference/products/flowker/list-executor-configurations)          |
| Obtener    | [`GET /v1/executors/{id}`](/es/reference/products/flowker/get-executor-configuration)       |
| Actualizar | [`PATCH /v1/executors/{id}`](/es/reference/products/flowker/update-executor-configuration)  |
| Eliminar   | [`DELETE /v1/executors/{id}`](/es/reference/products/flowker/delete-executor-configuration) |

Cada entrada lleva un `status`, que la API reporta en cada respuesta:

| Estado         | Descripción                                   |
| -------------- | --------------------------------------------- |
| `unconfigured` | La entrada aún no tiene detalles de conexión. |
| `configured`   | La entrada lleva detalles de conexión.        |
| `tested`       | La entrada se verificó.                       |
| `active`       | La entrada está en servicio.                  |
| `disabled`     | La entrada está fuera de servicio.            |

`PATCH` acepta `name`, `baseUrl`, `endpoints` y `authentication`, más los opcionales `description` y `metadata`. No acepta `status`, pero la operación de listado acepta `status` como filtro de query. La actualización aplica a las entradas en estado `unconfigured` o `configured`. La eliminación aplica a las entradas en estado `unconfigured`, `configured` o `disabled`. Ninguna operación de esta versión mueve una entrada a `tested`, `active` o `disabled`. La tabla lista esos valores porque las respuestas los reportan y el filtro de listado los acepta.

## Qué sigue

***

<CardGroup cols={2}>
  <Card title="Conceptos centrales" icon="diagram-project" href="/es/products/flowker/flowker-concepts">
    Entiende los workflows, los nodos, las aristas y las ejecuciones.
  </Card>

  <Card title="API de configuraciones de proveedor" icon="code" href="/es/reference/products/flowker/list-provider-configurations">
    Explora la API de configuración de proveedor.
  </Card>
</CardGroup>
