Relay docs

Workflows

A workflow is a saved, versioned graph of steps: a trigger, then models, knowledge searches, HTTP calls, integrations, branches, loops, waits, approvals and outputs, joined by edges and passing data with {{ }} bindings. Build it on the canvas in the panel (Workflows), test it in place, publish a version, and run it by hand, on a schedule, from a webhook, from your own app, or as a tool an agent can call.

#Triggers

Every workflow has exactly one trigger. Change its type from the trigger node's inspector.

  • Manual — the Test panel's Run button. Its sample input is used when you don't type one.
  • API — POST /v1/workflows/{id}/runs with a gateway key (scope workflows.run). An optional input schema checks required keys and primitive types.
  • Webhook — a URL of the form /v1/workflows/hooks/{token}. Generate it in the workflow settings; the token is the credential, so regenerate it if it leaks. trigger.input is { method, query, headers, body }. Optionally verify an HMAC-SHA256 signature of the body with a Signing secret credential. Respond immediately (202 + run id), with the run's output when it finishes, or from a Respond to webhook node.
  • Schedule — a 5-field cron in UTC. Saving an enabled, valid workflow arms it.
  • Error — the entry point of an error workflow: another workflow's settings name this one, and each failed production run starts it with { workflow, run, error }.

The API callable switch in the workflow settings also exposes the workflow as an OpenAI-compatible chat model at /v1/workflows/{id}/chat/completions.

#Data and bindings

Each node's output is available downstream as {{ nodes.<id>.output.<path> }}. Other roots: trigger.input, vars (written by Set variables), env (workspace variables), run (id, workflowName, testMode, resumeUrl…), and loop (item, index, first, last, count — inside a loop only). A value that is only a binding keeps its JSON type, so "{{ nodes.search.output.hits }}" passes a real array.

Type {{ in any field to autocomplete the paths that node may read. The Data tab of a node shows what flowed in and out on the last run; drag a key onto a field to insert its binding, or click it to copy.

Bindings are strict: a path that resolves to nothing fails the step instead of sending the literal text to a model. The compiler also rejects a binding to a node that isn't guaranteed to run first.

#Node catalogue

  • Model — LLM call, Library prompt, Agent, Classify (labels become output ports), Extract data (named, typed fields as JSON; works on every provider).
  • Knowledge & tools — Knowledge search, MCP tool, HTTP request, SQL query (SQL Server, parameterised, read-only by default).
  • Integrations — Slack, Teams, Outlook send mail, Microsoft Graph request, SharePoint list items / add item, Jira, ServiceNow, GitHub. Each is an HTTP request underneath, with every HTTP guard.
  • Logic — Branch, Switch, Loop over items, Merge, Wait, Run workflow, Stop.
  • Data — Set variables, Transform (a structured list of operations: map, filter, groupBy, sum, regexExtract, dateAdd, hash and ~40 more), Parse (JSON, CSV, XML, HTML → text).
  • Guardrails — Redact PII, Moderate, Approval.
  • Output — Return, Respond to webhook, Webhook, Send email.

#Loops

Everything connected after a Loop over items node's each port is its body and runs once per item; done continues once with results — one entry per item. Iterations can run in parallel (concurrency), items can be batched (batchSize), and continueOnItemError keeps a loop going past a failed item. A body may only be entered through each; the graph stays acyclic.

#Waiting, approvals and sub-workflows

  • Wait pauses for a duration, until a time, or until {{ run.resumeUrl }} is called. Anything longer than Gateway:Workflows:MaxInlineWaitSeconds (60) suspends the run durably, so it survives restarts.
  • Approval suspends the run until someone decides in Workflows → Approvals (or via POST /v1/workflows/runs/{id}/approve|reject), then takes the approved or rejected port. An optional Teams/Slack webhook is notified, and a timeout auto-rejects.
  • Run workflow runs another workflow as one step and returns its output. Depth is capped (Gateway:Workflows:MaxDepth) and recursion up the chain is refused.

#Testing

The Test panel runs the draft as a test run:

  • Dry run echoes prompts and describes HTTP calls instead of making them. Approvals take the approved port without waiting. Because upstream outputs are placeholders, a binding that doesn't resolve becomes empty instead of failing the step; the step's input lists those paths under _dryRunUnresolved, so check it for typos. To exercise the real flow without model spend, pin the model nodes' output and turn dry run off.
  • Pinned data (a node's Data tab → Pin this output) replaces that node's execution in test runs only. Published, API, schedule and webhook runs never use it.
  • Run node executes just the selected node, reusing upstream results from the last run. Run to here executes everything up to it.
  • Workspace variables resolve to their test value when one is set.

From a run's page: Retry replays the same graph and input, Retry from here reuses everything upstream of a node, and Debug in editor opens that run's data in the editor.

#Credentials and variables

Workflows → Credentials & variables. Credentials (bearer, API-key header, basic, query parameter, OAuth2 client credentials, SQL Server login, signing secret) are encrypted with Encryption:MasterKey and never returned to the browser. Each HTTP-style credential lists the hosts it may be sent to, and the gateway refuses to attach it anywhere else. Variables are plain values read as {{ env.NAME }} — not for secrets, since resolved values appear in step inputs.

#Outbound access

Nothing leaves the gateway unless an operator allows it:

  • Gateway:Workflows:Http:AllowedHosts — hosts HTTP, integration and webhook nodes may reach. Empty disables them. Private, loopback and link-local addresses are refused even when allow-listed, checked again at connect time, and redirects are not followed.
  • Gateway:Workflows:Sql:AllowedHosts — SQL servers the SQL node may connect to.
  • Gateway:Workflows:Email:AllowedDomains — recipient domains for Send email (SMTP from Gateway:HealthProbe:Smtp:*).

#Versions, access and portability

Snapshot and publish versions from Versions; production channels run the published version (or the draft when none is published). A workflow can be restricted so only its owner and chosen editors can change or run it. Export and import a workflow as JSON (pin data and webhook tokens are never exported), start from a template, or move many at once through the portability bundle.