> ## 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.

# Configuring a webhook trigger

> Start a Flowker workflow from an inbound HTTP call. Choose the payload contract, decide how the webhook answers, and confirm the route serves your caller.

A webhook trigger is the entry point of a workflow that starts from an inbound HTTP call. You declare a path and a method on the trigger node. When you activate the workflow, Flowker serves that path and runs the workflow on every call it accepts.

The trigger's `input_contract` decides which payloads Flowker accepts and how it decodes them. Choose it before you write the node: it is required, and it fixes the payload format for the whole route.

## Before you start

***

* A workflow in `draft` status. An active workflow is locked, so add the trigger before you activate it. See [Getting started with Flowker](/en/reference/flowker/flowker-api-quick-start) for the create-and-activate path.
* The `execute` permission on the `webhooks` resource for every system you let call the path. See [Securing a webhook](/en/flowker/integration-guide#securing-a-webhook).
* For the `xsd` contract: an XSD document in the registry. Upload it with [Upload an XSD schema](/en/reference/flowker/upload-xsd-schema) and keep the id it returns. Your deployment also needs the XML validation service the contract validates through — see [`XSD_VALIDATOR_URL`](/en/flowker/flowker-environment-variables).
* For the `openapi` contract: an OpenAPI document in the registry ([Upload an OpenAPI schema](/en/reference/flowker/upload-openapi-schema), covered end to end in [Connecting your own API](/en/flowker/connecting-your-own-api)). You also need the path and the method of the operation whose request body describes your payload. [Derive an operation schema](/en/reference/flowker/derive-openapi-operation-schema) shows you that request body.

## Step 1: Read the trigger contract from the catalog

***

Triggers are built in. You discover them in the catalog, and you never create one.

<Steps>
  <Step title="List the built-in triggers">
    [List catalog triggers](/en/reference/flowker/list-catalog-triggers) returns each trigger with its `id`, `name` and `version`. The webhook trigger's id is `webhook`.

    ```bash theme={null}
    curl -s http://localhost:4021/v1/catalog/triggers | jq .
    ```
  </Step>

  <Step title="Read the webhook trigger's schema">
    [Get a catalog trigger](/en/reference/flowker/get-catalog-trigger) returns the same fields plus `schema` — the JSON Schema Flowker validates your trigger node against. Read it when you want the field list from the running instance.

    ```bash theme={null}
    curl -s http://localhost:4021/v1/catalog/triggers/webhook | jq -r '.schema' | jq .
    ```
  </Step>
</Steps>

## Step 2: Choose the input contract

***

| Mode      | What the route accepts                  | What Flowker does with the payload                                                                                                       | Fields the mode requires                                  |
| --------- | --------------------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------- | --------------------------------------------------------- |
| `open`    | JSON or XML, as you declare in `format` | Decodes the body and runs no contract validation.                                                                                        | `format` — `"json"` or `"xml"`                            |
| `xsd`     | XML                                     | Validates the document against the XSD schema you referenced.                                                                            | `xsd_schema_id`                                           |
| `openapi` | JSON                                    | Validates the payload against exactly one operation of the OpenAPI document you referenced, and rejects a payload that does not conform. | `openapi_schema_id`, `operation_path`, `operation_method` |

The mode fixes the route's payload format. An `xsd` route is XML and an `openapi` route is JSON. An `open` route uses the `format` you declare, and `format` belongs to that mode only.

Choose `open` when the caller's payload has no published contract, or when you want the workflow itself to decide what is acceptable. Choose `xsd` when a partner sends XML that an XSD document defines. Choose `openapi` when a partner sends JSON and you hold the OpenAPI document that describes it.

<Note>
  An `openapi` route never accepts an unchecked payload: when Flowker cannot reach a verdict, it rejects the call with `FLK-0720`, and the workflow never sees that payload. An `xsd` route reaches its verdict through the XML validation service your deployment configures — a document that does not conform is rejected with `XML_VALIDATION_FAILED`, and a verdict Flowker cannot trust with `FLK-0720`. Configure that service before you put an `xsd` route in front of a caller.
</Note>

## Step 3: Decide how the webhook answers

***

| `response_mode`   | What the caller receives                                                                                                                                                                                                                                     |
| ----------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------ |
| `async` (default) | HTTP `202` with the execution receipt, as soon as the execution starts. The workflow continues in the background, and the caller reads the outcome from [Get execution results](/en/reference/flowker/get-execution-results).                                |
| `sync`            | Flowker holds the connection until the execution reaches a terminal state, for up to 15 seconds, then returns the outcome. If the window closes first, the caller receives the same `202` receipt plus a `Location` header pointing at the results endpoint. |

On a `sync` route, `response_view` shapes the body:

| `response_view`  | Body                                                                                                             |
| ---------------- | ---------------------------------------------------------------------------------------------------------------- |
| `full` (default) | The complete execution envelope: `executionId`, `workflowId`, `status`, `stepResults` and `finalOutput`.         |
| `final_output`   | Only the execution's final business output.                                                                      |
| `receipt`        | The lean receipt: `executionId`, `workflowId`, `status` and `startedAt`.                                         |
| `passthrough`    | The shape the terminal step implies — a relayed provider response, or a terminal `set_output` node's own output. |

`response_view` is inert on an `async` route. For the full `passthrough` rules and for the `responseStatusCode` override, see [Synchronous response mode](/en/flowker/integration-guide#synchronous-response-mode).

<Tip>
  Pick `async` when the caller only needs to know the event arrived. Pick `sync` when the caller needs the answer in the same call — a partner that expects a decision on the same connection, for example.
</Tip>

## Step 4: Write the trigger node

***

The webhook trigger is a node with `type: "trigger"` and these fields in its `data`:

| Field               | When you set it | Value                                                                                                  |
| ------------------- | --------------- | ------------------------------------------------------------------------------------------------------ |
| `triggerType`       | Always          | `"webhook"`.                                                                                           |
| `path`              | Always          | The path to serve, such as `"payments/received"`. It carries as many segments as you need.             |
| `method`            | Always          | The method the route answers: `GET`, `POST`, `PUT`, `PATCH` or `DELETE`, in upper case.                |
| `input_contract`    | Always          | `"open"`, `"xsd"` or `"openapi"`.                                                                      |
| `format`            | With `open`     | `"json"` or `"xml"`.                                                                                   |
| `xsd_schema_id`     | With `xsd`      | The id [Upload an XSD schema](/en/reference/flowker/upload-xsd-schema) returned.                       |
| `openapi_schema_id` | With `openapi`  | The id [Upload an OpenAPI schema](/en/reference/flowker/upload-openapi-schema) returned.               |
| `operation_path`    | With `openapi`  | The operation path as the OpenAPI document writes it, such as `"/orders"`. Flowker matches it exactly. |
| `operation_method`  | With `openapi`  | The operation's method: `GET`, `POST`, `PUT`, `PATCH` or `DELETE`.                                     |
| `response_mode`     | Optional        | `"async"` (default) or `"sync"`.                                                                       |
| `response_view`     | Optional        | `"full"` (default), `"final_output"`, `"receipt"` or `"passthrough"`.                                  |

The trigger configuration is a closed contract. Saving a workflow whose webhook trigger omits `path`, `method` or `input_contract`, misses a field its `input_contract` mode requires, names another mode's schema id or operation field, or carries a key or a value the schema does not accept fails with `FLK-0934`.

<CodeGroup>
  ```json open JSON theme={null}
  {
    "id": "trigger-1",
    "type": "trigger",
    "name": "Payment received",
    "position": { "x": 0, "y": 0 },
    "data": {
      "triggerType": "webhook",
      "path": "payments/received",
      "method": "POST",
      "input_contract": "open",
      "format": "json"
    }
  }
  ```

  ```json open XML theme={null}
  {
    "id": "trigger-1",
    "type": "trigger",
    "name": "Statement received",
    "position": { "x": 0, "y": 0 },
    "data": {
      "triggerType": "webhook",
      "path": "statements/received",
      "method": "POST",
      "input_contract": "open",
      "format": "xml"
    }
  }
  ```

  ```json xsd theme={null}
  {
    "id": "trigger-1",
    "type": "trigger",
    "name": "STR0008 received",
    "position": { "x": 0, "y": 0 },
    "data": {
      "triggerType": "webhook",
      "path": "spb/str0008",
      "method": "POST",
      "input_contract": "xsd",
      "xsd_schema_id": "0f9a1c3e-5b7d-4c2a-9e18-6d4b2f7a1c05"
    }
  }
  ```

  ```json openapi theme={null}
  {
    "id": "trigger-1",
    "type": "trigger",
    "name": "Order paid",
    "position": { "x": 0, "y": 0 },
    "data": {
      "triggerType": "webhook",
      "path": "orders/paid",
      "method": "POST",
      "input_contract": "openapi",
      "openapi_schema_id": "3c7e9b21-84af-4d6c-b0f1-2a5c8e93d7b4",
      "operation_path": "/orders",
      "operation_method": "POST"
    }
  }
  ```

  ```json sync response theme={null}
  {
    "id": "trigger-1",
    "type": "trigger",
    "name": "Authorize payment",
    "position": { "x": 0, "y": 0 },
    "data": {
      "triggerType": "webhook",
      "path": "payments/authorize",
      "method": "POST",
      "input_contract": "open",
      "format": "json",
      "response_mode": "sync",
      "response_view": "passthrough"
    }
  }
  ```
</CodeGroup>

Flowker registers the path with a leading slash and without a trailing one, so `payments/received`, `/payments/received` and `payments/received/` all register the same route.

## Step 5: Activate the workflow

***

<Steps>
  <Step title="Create the workflow">
    Send the node with the rest of your workflow to [Create a workflow](/en/reference/flowker/create-workflow). The workflow lands in `draft` status, and Flowker validates the trigger configuration here — a contract error answers `FLK-0934`.
  </Step>

  <Step title="Activate it">
    Call [Activate a workflow](/en/reference/flowker/activate-workflow). Activation registers the path and the method. It also resolves what the contract references. A missing XSD schema answers `FLK-0930` and a missing OpenAPI schema `FLK-0931`. An operation the document does not declare answers `FLK-0932`, and an operation with no request body answers `FLK-0933`.

    ```bash theme={null}
    curl -s -X POST http://localhost:4021/v1/workflows/019c96a0-0ac0-7de9-9f53-9cf842a2ee5a/activate | jq .
    ```
  </Step>
</Steps>

One active workflow owns a path and method pair within your tenant. Activating a second workflow on the same pair answers `FLK-0360`. [Deactivating a workflow](/en/reference/flowker/deactivate-workflow) releases its routes, so you can hand a path to a new version.

## Step 6: Call the route and confirm it works

***

Send the call the way your caller will:

```bash theme={null}
curl -i -X POST http://localhost:4021/v1/webhooks/payments/received \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: 7f3e1a2b-4c5d-6e7f-8a9b-0c1d2e3f4a5b" \
  -d '{ "transactionId": "txn-123", "amount": 1500.00 }'
```

An `async` route answers `202` with the receipt:

```json theme={null}
{
  "executionId": "019c96a0-10ce-75fc-a273-dc799079a99c",
  "workflowId": "019c96a0-0ac0-7de9-9f53-9cf842a2ee5a",
  "status": "running",
  "startedAt": "2026-03-18T14:35:00Z"
}
```

A `sync` route answers with the execution's outcome, in the shape its `response_view` selects. The status it carries depends on the view and on how the execution ended — [Synchronous response mode](/en/flowker/integration-guide#synchronous-response-mode) holds those rules.

Three signals tell you the route worked:

* A response that started an execution carries `X-Webhook-Workflow-ID` and `X-Webhook-Execution-ID`, so you can tie a call to the workflow it reached and the execution it started.
* [Get execution results](/en/reference/flowker/get-execution-results) reports the step results and the final output for that `executionId`.
* The execution's input carries a `_webhook` object with the method, the path and the caller's address. Use it to confirm the workflow saw the call it should. See [Webhook metadata](/en/flowker/integration-guide#webhook-metadata).

A repeat delivery that carries the same `Idempotency-Key` returns the original execution instead of starting a second one, and its body carries `idempotencyReplayed: true` with the original `status`. Send a new key to run the workflow again.

The five verbs each have their own reference page: [POST](/en/reference/flowker/trigger-webhook), [GET](/en/reference/flowker/trigger-webhook-get), [PUT](/en/reference/flowker/trigger-webhook-put), [PATCH](/en/reference/flowker/trigger-webhook-patch) and [DELETE](/en/reference/flowker/trigger-webhook-delete).

## When a call fails

***

| Code                    | When it happens             | What to do                                                                                                                                                  |
| ----------------------- | --------------------------- | ----------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `FLK-0934`              | You save the workflow.      | Compare the trigger `data` against the field table in [Step 4](#step-4-write-the-trigger-node). Check this code first when a webhook trigger does not save. |
| `FLK-0930` … `FLK-0933` | You activate the workflow.  | Confirm the schema id, and for `openapi` confirm the operation path and method exist in the document and that the operation declares a request body.        |
| `FLK-0360`              | You activate the workflow.  | Another active workflow owns that path and method. Choose another path, or deactivate the other workflow.                                                   |
| `FLK-0361`              | The caller sends a request. | No route answers that path and method. Confirm the workflow is active, and that the caller uses the method the trigger declares.                            |
| `FLK-0501`              | The caller sends a request. | The workflow resolved but is not active. Activate it.                                                                                                       |
| `FLK-0001`              | The caller sends a request. | The body of a JSON route is not valid JSON.                                                                                                                 |
| `FLK-0364`              | The caller sends a request. | The body of an XML route is not well-formed XML. An XML route reports it as `XML_MALFORMED` in the `<error>` document.                                      |
| `XML_VALIDATION_FAILED` | The caller sends a request. | The body of an `xsd` route is well-formed XML but does not conform to the XSD document. The `<error>` document names the failing line and column.           |
| `FLK-0935`              | The caller sends a request. | The JSON body of an `openapi` route does not conform to the pinned operation's request body. The message names the failing field.                           |
| `FLK-0720`              | The caller sends a request. | Flowker could not validate the payload, so it rejected the call. Confirm the validation service and the referenced schema are available to your deployment. |
| `FLK-0363`              | The caller sends a request. | The body is over 1 MB. Send less in one call.                                                                                                               |

A JSON route returns `code`, `title` and `message`. An XML route returns an `<error>` document. See the [Flowker error list](/en/reference/flowker/flowker-error-list) for every code and both shapes.

## What's next

***

<CardGroup cols={2}>
  <Card title="Integration guide" icon="plug" href="/en/flowker/integration-guide">
    Connect the workflow to external services, and read the full synchronous-response rules.
  </Card>

  <Card title="Workflow design guide" icon="diagram-project" href="/en/flowker/workflow-design-guide">
    Build the rest of the graph the trigger enters.
  </Card>
</CardGroup>
