Workflows
A workflow is a graph of steps that runs when an event is sent, on a schedule, or when you start it yourself. Each step receives the output of the step before it. The dashboard has a visual builder; the same workflow can be created through the API.
How a workflow runs
Section titled “How a workflow runs”- A trigger starts the run with the event’s
dataas input. - Nodes run in topological order: a node starts only after every node it depends on has finished.
- Each node’s output becomes the input of the nodes it connects to. A node with several outgoing edges fans out.
- A
filternode that does not match skips everything downstream of it. Abranchnode sends the run down itstrueor itsfalseedge. - Every step records its status, input, output and duration, so a run can be read back step by step. List runs with
GET /api/v1/projects/{projectId}/workflows/{id}/executions.
Triggers
Section titled “Triggers”triggerType |
Starts a run |
|---|---|
WEBHOOK_EVENT (default) |
For each event whose type matches triggerConfig.eventTypePattern. Without a pattern, for every event in the project. A workflow runs at most once per event. |
MANUAL |
When you call POST /api/v1/projects/{projectId}/workflows/{id}/trigger. The JSON body is the input. |
SCHEDULE |
At the times given by triggerConfig.cron in triggerConfig.timezone. The input is {"scheduledFor": "<the tick>"}. |
Schedules
Section titled “Schedules”cron has five fields: minute, hour, day of month, month, day of week, as in 0 9 * * 1-5 for 09:00 on weekdays. A sixth field for seconds is refused, so a workflow runs at most once a minute. timezone is an IANA name such as Europe/Kyiv, default UTC; a daily run keeps its local hour across daylight saving changes. An invalid expression or zone is refused with 400 when the workflow is saved.
A run starts within about ten seconds of its time and goes through the same queue as event-triggered runs. If Railhook was down over several ticks, the workflow runs once when it comes back, not once per missed tick. Each run records scheduledFor, and a tick never runs twice, even with several API instances. The next run time is nextRunAt on the workflow; a disabled workflow has none. GET /api/v1/projects/{projectId}/workflows/schedule-preview?cron=...&timezone=... returns the next three run times without saving anything.
Turn a workflow on or off with PATCH /api/v1/projects/{projectId}/workflows/{id}/toggle.
Node types
Section titled “Node types”type |
What it does | Config in data |
|---|---|---|
webhookTrigger |
The entry point. Passes the trigger input on. | none |
filter |
Continues only when the conditions match; otherwise downstream nodes are skipped. | conditions, the same condition tree as rules |
branch |
Evaluates the conditions and follows the true or the false edge. No conditions means true. |
conditions |
transform |
Reshapes the data. A saved transformation wins when both are set; one that cannot be found fails the step. | transformationId, or template with {{field.path}} placeholders |
http |
Calls a URL and passes the response on. | url (required), method (default POST), headers, body (default: the input), timeout in seconds, 1 to 60, default 30 |
slack |
Posts a message to a Slack incoming webhook. | webhookUrl, message, channel |
delivery |
Delivers the data to an existing endpoint through the normal delivery pipeline, with its retries. The data is recorded as an event in the endpoint’s project, which counts toward the month’s events like any other. | endpointId (required), eventType (default workflow.delivery) |
createEvent |
Sends a new event into Railhook, which then goes through rules and subscriptions like any other and counts toward the month’s events. The project has to be one of your organization’s; saving a workflow that names any other is refused. | projectId, eventType (both required), payloadTemplate (default: the input) |
delay |
Pauses the run, without holding a worker thread. | delaySeconds, 1 to 300, default 5 |
Create a workflow
Section titled “Create a workflow”A definition is a list of nodes, each with an id, a type and its data, and a list of edges from source to target. An edge leaving a branch node sets sourceHandle to "true" or "false".
curl -X POST "$RAILHOOK_URL/api/v1/projects/$PROJECT_ID/workflows" \ -H "X-API-Key: $API_KEY" \ -H "Content-Type: application/json" \ -d '{ "name": "Big orders to the fraud service", "enabled": true, "triggerType": "WEBHOOK_EVENT", "triggerConfig": { "eventTypePattern": "order.*" }, "definition": { "nodes": [ { "id": "start", "type": "webhookTrigger", "data": {} }, { "id": "big", "type": "filter", "data": { "conditions": { "type": "predicate", "field": "amount", "operator": "GTE", "value": 1000, "valueType": "NUMBER" } } }, { "id": "check", "type": "http", "data": { "url": "https://fraud.example.com/check", "method": "POST" } } ], "edges": [ { "source": "start", "target": "big" }, { "source": "big", "target": "check" } ] } }'Time limits
Section titled “Time limits”| Limit | Default |
|---|---|
| One run, end to end | 600 seconds |
| One node | 30 seconds |
An http or slack node |
60 seconds |
A createEvent node |
30 seconds |