Back to Inputs

HTTP Webhook

input

Trigger your workflow via HTTP requests. This input type creates an HTTP server that listens for incoming requests and triggers the workflow when a request is received.

Configuration

Add an HTTP webhook input to your workflow to create an endpoint that can receive HTTP requests:

workflow:
  name: my-webhook-workflow
  description: "Receives HTTP requests"
  input:
    type: http_webhook

Configuration Options

Required and optional configuration fields for this input type:

Parameter Type Required Description
type string Yes Set to "http_webhook"

Workflow Endpoint

After creating your workflow, the webhook endpoint details will be available on the workflow details tab. The endpoint URL follows this pattern:

https://pipeline.etlr.io/v1/webhooks/{organization_id}/{workflow_id}/{security_hash}

The URL contains three components:

  • organization_id - Your organization's unique identifier
  • workflow_id - The specific workflow's unique identifier
  • security_hash - A security token that provides authentication through obscurity

Triggering the Webhook

Send an HTTP POST request to your workflow's endpoint to trigger execution. The request body will be available in the workflow state:

curl -X POST \
  https://pipeline.etlr.io/v1/webhooks/a7b3c468-2e1d-49af-8ea0-fb9edc2dd847/752d84fe-cadf-48c0-ba69-ce4bf792gd7e/d448feb6c9da97b60847f1c21cbf9e6c8b378bfb7f04cc6cc0c4d4f992f75ed5 \
  -H "Content-Type: application/json" \
  -d '{
  "user": {
    "name": "John Doe",
    "email": "[email protected]"
  },
  "action": "signup"
}'

Request Data

The HTTP request body is automatically parsed and made available in your workflow state. The JSON request body fields are available at the root of the state, allowing you to access them directly in your workflow steps.

For example, if you send this request body:

{
  "user": {
    "name": "John Doe",
    "email": "[email protected]"
  },
  "action": "signup"
}

You can access the data in your workflow in two ways:

  • Using input_from - Most steps have an input_from parameter to read data from specific paths in the state (e.g., input_from: user.name). See the State documentation for more details.
  • Using template strings - When a step supports templates (like text_template), you can inject values using ${user.name} syntax for string interpolation.

Example Workflow

Here's a complete example that receives webhook data, adds a timestamp, and sends it to Slack:

workflow:
  name: webhook-to-slack
  description: "Receives webhooks and posts to Slack"
  input:
    type: http_webhook
  steps:
    - type: add_timestamp
      field: received_at
    - type: slack_webhook
      webhook_url: "${env:SLACK_WEBHOOK_URL}"
      text_template: "New event: ${user.name} performed ${action} at ${received_at}"

Response

By default, the webhook is fire-and-forget: it responds with a 200 OK immediately after accepting the request and continues running the workflow in the background.

{
  "status": "ok",
  "upstream_status": 200,
  "upstream_body": "{\"status\":\"accepted\",\"request_id\":\"157b931ef623a667\"}"
}

Synchronous Mode (?wait=true)

Append ?wait=true to the webhook URL to make the request block until the workflow finishes. The response body contains the final workflow state, so you can use a webhook as a request/response endpoint — for example, to trigger an LLM step and return its answer inline.

curl -X POST \
  'https://pipeline.etlr.io/v1/webhooks/{org}/{workflow}/{hash}?wait=true' \
  -H "Content-Type: application/json" \
  -d '{"ticket": {"subject": "Cannot log in"}}'

The response uses a consistent envelope with a status field your client can switch on:

Status HTTP code Meaning
"ok" 200 Workflow finished successfully. The event field contains the final state after all steps.
"dropped" 200 A step filtered out the event (returned None). No event field.
"timed_out" 200 The workflow didn't finish within 30 seconds. It keeps running in the background — check your logs for completion.
"error" 200 A step raised an exception. The error field contains the exception type and message.

Example success response:

{
  "status": "ok",
  "request_id": "157b931ef623a667",
  "event": {
    "ticket": { "subject": "Cannot log in" },
    "triage": { "urgency": "high", "category": "account" },
    "request_id": "157b931ef623a667"
  }
}

Example timeout response (workflow still running in the background):

{
  "status": "timed_out",
  "request_id": "157b931ef623a667"
}

Key points:

  • 30-second cap — if the workflow takes longer, the response returns with "timed_out" but the workflow continues to completion. It is never cancelled by the webhook.
  • Accepted truthy values?wait=true, ?wait=1, or ?wait=yes. Any other value (or absence) falls back to the default fire-and-forget behaviour.
  • Choose wait for short, interactive workflows — it's ideal for synchronous LLM calls, enrichment, and validation. Long-running pipelines should stay fire-and-forget and signal completion another way.

Best Practices

  • Endpoint Security - Keep your webhook URL private, as the security hash provides authentication
  • Validation - Use filter steps to validate incoming data structure and content
  • Error Handling - Handle invalid requests gracefully with proper error responses
  • Rate Limiting - Be aware of rate limits on your workflow executions
  • Testing - Test your webhooks thoroughly before deploying to production