Browse documentation
Guide

Triggers and webhooks

What starts a workflow run — webhook, schedule, or Kafka topic — and how to point an external system at your webhook URL.

View as Markdown

A trigger is the reason a run exists. Every workflow that is not a subflow needs at least one before it can be activated, and every run records which trigger started it.

Trigger types

Triggers are created through the wizard that opens with a new workflow, never from the step palette. Its first screen offers four choices, three of which create a trigger:

Choice What it does
Webhook Receives HTTP POSTs from external systems. Requires a service account for auth.
Scheduled Runs on a recurring interval, cron-like.
Kafka Consumes messages from a Kafka topic. Requires a Kafka connector.
No trigger (subflow) Creates a reusable subflow invoked by other workflows.

One more trigger type exists — change data capture, which appears as CDC in the Type filter on the workflows list — but it has no card in the wizard today.

Afterwards, select the trigger node on the canvas to see and change its configuration in the inspector.

Webhook triggers

Set one up

Pick Webhook in the wizard. The second screen asks for a Service account, and it is mandatory — Hodoflow does not accept unauthenticated ingestion. Only active service accounts holding the webhooks scope are listed, and the help text beneath the picker explains why:

External callers must present a JWT issued from this service account to fire the webhook.

Create one first at Settings → Service Accounts if you need to. See Service accounts.

Save the workflow. Until you do, the trigger inspector says Save workflow to generate webhook token — the token is minted on save. Afterwards the inspector shows the URL in a read-only Webhook URL field.

Call it

The canonical form is token-only. The token identifies the trigger, the organization, and the workspace all by itself, so nothing in the URL depends on your organization's name.

curl -X POST https://app.example.com/api/v1/webhooks/YOUR_TRIGGER_TOKEN \
-H "Authorization: Bearer $ACCESS_TOKEN" \
-H "Content-Type: application/json" \
-d '{"order_id": "A-123", "total": 250}'

$ACCESS_TOKEN is a short-lived JWT you exchange your service account's client ID and secret for, and it must carry the webhooks scope. Service accounts walks through the exchange.

An accepted delivery returns 202 Accepted with the id of the run it started:

{"status": "accepted", "workflow_run_id": "0198f2c1-..."}

The other answers you can get are 401 when the credential is missing or wrong, 403 when it authenticated but lacks the webhooks scope, 404 when no active trigger matches the token, and 422 when the payload could not be processed. A 404 is also what an inactive workflow's webhook looks like, since only active triggers are served.

Retries and duplicates

Hodoflow recognises a redelivery of something it already accepted and answers 202 with {"status": "duplicate"} instead of starting a second run. That way a sender retrying an acknowledgement it never saw stops retrying, without double-processing.

Identity comes from whichever of these headers your sender provides: Idempotency-Key, X-GitHub-Delivery, X-Shopify-Webhook-Id, or X-Twilio-Idempotency-Token. With none of them, Hodoflow falls back to hashing the token and the raw body inside a two-hour window, so a byte-identical payload is treated as a duplicate within that window and processes normally in a later one.

Limits

Ingestion is capped at 100 requests per minute per trigger token, and bodies at 1 MB. Both are enforced before any work is done: over the rate you get a 429 with a Retry-After header, and over the size you get a 413.

Discovering the payload shape

The steps below a trigger can only offer you fields they know about, so the inspector has an Output Schema section with a Refresh Schema button. Press it and Hodoflow starts listening, showing a Test URL (no data saved) and Waiting for a test POST request.... Post a representative payload to that URL and the field names appear as N fields found. Nothing is stored and no run is created.

Verifying the sender

A webhook trigger can also point at an inbound connector, chosen under Inbound Authentication in the inspector, to verify signatures or API keys on top of the service account's token. The picker only appears when your organization has inbound connectors that carry an authentication method — see Credentials and connections.

Scheduled triggers

Pick Scheduled and give it either an interval in minutes or a cron expression. The inspector afterwards shows the schedule in plain language with an Edit schedule button to change it.

An interval below one minute is rejected, as is a cron expression that does not parse. Deactivating the workflow cancels its scheduled jobs; reactivating recreates them.

Kafka triggers

Pick Kafka and choose a Kafka connector. The topic and consumer group live on the connector, not the trigger, so several workflows can read the same configured topic without repeating its settings. Set the connector up first at Connectors → Inbound — see Credentials and connections.

The Kafka trigger inspector has Sample schema from topic, which reads a message off the topic to populate the fields your downstream steps and mappings will offer.

Activating a workflow starts its consumers; deactivating stops them.

Going deeper

The wire-level reference — request and response bodies, every status code, header names, and the token exchange — is on the developer portal at webhook ingestion.