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.