Building Flows
Building Flows
Creating a Flow
POST /api/flowsContent-Type: application/json
{ "name": "Invoice Processing Pipeline", "enabled": true, "category": "Finance", "groupId": "65abc000"}Response:
{ "id": "65abc123", "name": "Invoice Processing Pipeline", "enabled": true, "permanentId": "inv-proc-pipeline", "version": 1, "createdAt": "2024-01-15T10:00:00Z"}Key fields:
- enabled: only enabled flows can be triggered (except via direct API calls with
force: true) - permanentId: stable across versions β use this to reference the flow from external systems
- version: incremented on every update β useful for tracking changes
Adding Flowlets (Steps)
Each step references a module by its appId and provides the arguments that module needs:
POST /api/flows/65abc123/layersContent-Type: application/json
{ "name": "Download Invoice PDF", "ref": "downloadPdf", "appId": "curl", "index": 0, "args": { "method": "GET", "url": "{{ $prev.input.pdfUrl }}", "responseType": "binary" }, "timeout": 30, "retry": { "count": 3, "delayMs": 1000, "backoffMultiplier": 2 }}The ref field is critical β itβs how downstream steps reference this stepβs output:
{{ $prev.downloadPdf.body }} β access the PDF bytes{{ $prev.downloadPdf.statusCode }} β access the HTTP statusStep Ordering
The index field controls execution order. Steps with the same index run in parallel. Steps with a higher index run after all lower-index steps complete.
index: 0 β [fetchData]index: 1 β [parseData, validateData] β parallelindex: 2 β [saveResult]Conditional Execution with Filters
Add filters to a flowlet to make it conditional:
{ "ref": "sendAlert", "appId": "send-mail", "filters": [ { "leftValue": "{{ $prev.validateData.isValid }}", "operator": "eq", "rightValue": "false", "mode": "and" } ]}If all filters pass, the flowlet runs. If any fail, it is marked FILTERED and skipped.
Available operators: eq, neq, gt, gte, lt, lte, contains, not_contains, is_empty, not_empty.
Flow Groups
Groups organize flows in the UI and share KV scope. Create a group:
POST /api/groups{ "name": "Finance Automation", "index": 0}Then assign flows to it by setting groupId when creating or updating the flow.
Updating a Flow
PUT /api/flows/65abc123{ "name": "Invoice Processing Pipeline v2", "enabled": true}Each update increments the version field. Existing plays reference the version that was active when they ran.
Enabling and Disabling
# Disable a flow (prevents new triggers)PUT /api/flows/65abc123{"enabled": false}
# Re-enablePUT /api/flows/65abc123{"enabled": true}