Skip to main content

Workflows Overview

Workflows let you build automated processes that chain API calls, app connectors, and AI steps; branch on conditions; loop over data; and recover from errors — all through a visual builder. Executions are durable: they run on a dedicated worker backed by a job queue, survive restarts, resume delays on time, and can be cancelled and retried from a failed step.

What Are Workflows?

A workflow is a graph of nodes that runs in response to a trigger or a manual/API invocation. Example workflow:

Key Concepts

Nodes

Nodes are the building blocks of a workflow. Each node performs one action. Node types are grouped by category:
The Code Block node runs real JavaScript in a sandbox now — it is no longer a pass-through stub. See Code Block Node.

Edges

Edges connect nodes and define execution flow. The engine uses frontier traversal with branch routing: a node runs only when its incoming edges are resolved and at least one is active. Condition and Router nodes activate specific outgoing edges (by sourceHandle), and inactive branches are recorded as skipped steps so the canvas greys them out — every node no longer runs on every execution.

Variables

Reference data from anywhere in the run with {{ ... }} expressions. The following namespaces are available:
Unknown names are left literal (they are not replaced with undefined). For an HTTP Request node the response payload is exposed under .body (status, statusText, headers, body, url, method, success).

Node Types

Trigger Node

Every workflow starts with exactly one trigger node that determines when it runs:
  • Manual — run on demand from the UI or API.
  • Schedule — run on a cron expression (exactly-once across the worker fleet).
  • Webhook — run when an HTTP request hits the workflow’s /hooks/wf/:token URL.
  • Inbound Webhook — fan out from a shared inbound webhook to this workflow.
  • Route Event — run when a KnoxCall route processes a request (proxy_event).
  • App Event — run instantly when a connected app sends a provider webhook (e.g. a GitHub issue).
  • App Polling — run when polling a connected app surfaces a new item.
See Triggers for configuration and delivery details.

HTTP Request Node

Make HTTP requests to external APIs. Config is nested under data.config:
Output (response payload under body):

App Connector Nodes

Instead of hand-rolling an HTTP Request against a provider, use a connected app. Each connector operation appears as an action node (for example Slack → Send Message, SendGrid → Send Email, Notion → Create Page). The node references a saved Connection and KnoxCall injects the credentials and calls the provider through its SSRF-pinned, host-allowlisted transport. Ten apps ship in the catalog: SendGrid, Stripe, Twilio, Slack, GitHub, Notion, Linear, Discord, Airtable, and Telegram.

AI Node

Run an Anthropic model as a workflow step with structured output — no prompt-parsing glue. Four operations:
  • Classify — pick one label from a candidate list.
  • Extract — pull named fields out of text into a typed object.
  • Summarize — condense text to a target length.
  • Generate — free-form generation with a token cap.
AI steps use your tenant Anthropic key when one is configured (Integrations), otherwise the platform key. They count as weighted operations (×3) and draw from your monthly AI-token budget. See AI in Workflows.

Code Block Node

Run custom code in a secure sandbox — for transforms, calculations, and formatting. JavaScript/TypeScript runs in an in-process QuickJS-WASM sandbox; Python runs in a network-less container jail. Pick the language in the node’s inspector.
For fan-in (multiple incoming edges), input is an array of { nodeId, output } entries keyed by node id. Neither sandbox has network, filesystem, or timer access; each enforces a wall-clock timeout and a memory cap. Python requires Docker on the workflow worker (self-hosted installs without Docker get a clear “requires Docker” error).

Data Transform Node

Reshape data declaratively (map/pick/rename fields) without writing code — useful when a Code Block would be overkill.

Condition Node

Branch on a structured list of conditions (not a JavaScript string):
Each condition has a type, a JSONPath path, and a value. Conditions are combined with logic (AND/OR). The node activates its True or False outgoing edge; the other branch is skipped. Supported types: equals, not_equals, greater_than, less_than, greater_or_equal, less_or_equal, contains, starts_with, ends_with, exists, is_empty, regex.

Router Node

Route to one or more of several named paths:
executionMode is sequential (first match wins) or parallel (every matching route runs). A route with isFallback: true handles input that matches no other route.

Loop Node

Iterate over an array or repeat while a condition holds. Loops are an engine construct: the loop body is a real subgraph (branches and nested loops allowed), each iteration produces linked step rows, and while loops thread the previous iteration’s output.
Reference the current element with {{loop.item}} and its position with {{loop.index}}. loopType is array (via arrayConfig) or while (via whileConfig); maxIterations is a required safety cap. batchSize > 1 processes items in parallel batches.

Delay Node

Pause execution:
Short delays sleep in-process (abortable on cancel). Long delays are durable: the execution suspends to a waiting state with an encrypted checkpoint and resumes on schedule — even across a worker restart. delayType is duration (with duration + unit: seconds/minutes/hours) or until (with an ISO timestamp).

Merge Node

Join multiple incoming branches back into one. Modes: all (wait for every non-skipped branch), first (take the first to arrive), or n (wait for N). Emits an array or a merged object.

Set Variable Node

Write a value into the {{vars.*}} namespace for later nodes to read.

Error Handler Node

React to an error on its input and apply a strategy:
onError is continue, retry, or fallback. Retries are durable (scheduled with backoff via the queue, not a blocking sleep), so a retrying step survives a restart.

Durable Execution

Workflows run on a dedicated background worker backed by a durable job queue (pg-boss). This gives you:
  • Crash safety — if the worker restarts mid-run, the execution resumes from its last checkpoint; completed steps are never re-run.
  • Real cancellation — cancelling aborts in-flight work (including HTTP requests), not just a database flag.
  • Timeouts — a run that exceeds its timeout_seconds is marked timed_out.
  • Exactly-once scheduling — scheduled and polling triggers fire once across the whole worker fleet (row-locked, no duplicates).
  • Per-tenant concurrency — runs beyond your concurrency limit are queued, not dropped.
Execution states: queued → running → { completed | failed | cancelled | timed_out }, with running → waiting → running for durable delays/retries and paused for concurrency deferral.

Executing Workflows

Manual Execution (UI)

  1. Open the workflow and click Run.
  2. Optionally provide input data.
  3. Watch each node light up live on the canvas.

Via the public API

Workflows are a first-class /v1 resource. Queue a run with a short-lived OAuth token (see Authentication):
The run is queued and the call returns 201 immediately:
Sending the same X-Idempotency-Key again returns the same execution (with an X-Idempotent-Replay: true header) instead of starting a second run. See Using the Workflows API for the full CRUD + executions surface.

Via a webhook

A workflow with a Webhook trigger gets a signed URL of the form https://api.knoxcall.com/hooks/wf/{token}. POST to it to run the workflow. See Triggers.

Monitoring Executions

  • Live progress — nodes highlight as they start; success/failure and duration show per node; skipped branches are greyed.
  • Execution history — the Executions tab lists every run with status, start time, duration, and trigger type.
  • Execution details — open a run to see each step’s (redacted) input/output, errors, and timing. Secret values always appear as [REDACTED].
  • Webhook notifications — subscribe an outbound webhook to workflow.execution.completed / workflow.execution.failed to be notified when runs finish.

Versioning, Draft & Publish

The workflow you edit is a draft; the workflow that runs is the published version. Autosave writes to the draft without affecting live runs. Publish validates the graph, snapshots a new version, and switches live behavior. Every execution pins the workflow_version it ran against. One-click rollback is available: open the Versions tab and Restore any prior version (it loads into your draft, so you review before publishing).

Templates

Start from a pre-built Template instead of a blank canvas. Templates land as a disabled draft so you can wire in your own connections and secrets before enabling.

Best Practices

  1. Start simple — Trigger → HTTP Request, then add Condition/Router as needed.
  2. Name nodes descriptively — “Fetch Customer Data”, not “HTTP Request 1”.
  3. Use connections and secrets — never hard-code credentials in a node.
  4. Add error handling on external calls and critical paths.
  5. Test before enabling — run manually and use per-node Test in the inspector.
  6. Watch executions — check history for failure patterns and slow steps.

Next Steps

Creating Workflows

Step-by-step build guide

Connections

Connect Slack, GitHub, Stripe, and more

Triggers

Schedule, webhook, and app triggers

AI in Workflows

AI steps and the workflow copilot

Templates

Start from a pre-built workflow

Using the API

Manage and run workflows via /v1

Statistics

  • Level: intermediate
  • Time: 10 minutes

Tags

workflows, automation, orchestration, visual-builder, durable