Node reference
Every node you can add to a workflow, grouped the way the builder palette groups them: Triggers, Integrations, AI, Flow, and Core (with its Tables section). Each entry gives the node's key, ports, main parameters, and the output fields you can reference.
How to read this reference
A node's key is a prefix plus its normalized name. The prefix depends on the node family: trigger:, mcp: (integration steps), agent: (AI nodes), core:, table:, interface:, and note:. The name is lowercased, accents are transliterated, every other character becomes _, and repeats and edges are trimmed. A node you name Fetch Orders is therefore core:fetch_orders, and you read its output with {{core:fetch_orders.output.<field>}}. See Expressions for the full syntax.
Ports exist only on branching nodes. When you wire an edge from a port, you address it as key:port, for example core:check:if or agent:route:category_0. Numbered ports start at 0.
Outputs listed here are the fields a node stores after it runs. Only these declared fields are kept, so they are the ones you can reference downstream. The inspector may show extra run details (such as the resolved parameters) that are not part of the output.
Triggers
A trigger starts a run. A workflow can have several triggers, and each one drives its own part of the graph. Configuration details for each trigger are on the Triggers page.
| Palette name | Starts a run when | Main outputs |
|---|---|---|
| Webhook | An HTTP request reaches the workflow URL. | payload, headers, query, method, triggered_at |
| Manual | Someone runs the workflow on demand. | triggered_at, triggered_by |
| Tables | A row changes in a built-in table. | row, previous_row, event_type, row_id, triggered_at |
| Workflows | Another workflow completes. | parentWorkflowId, parentRunId, parentStatus, result, parentStatistics |
| Error | A run of the workflow it watches fails. | parentWorkflowId, parentRunId, status, errorMessage, failedSteps, completedSteps, totalSteps, skippedSteps |
| Chat | A chat message arrives (optionally matching a rule). | message, extracted_message, conversation_id, attachments, matched |
| Scheduler | A cron expression or time interval comes due. | triggered_at, execution_count, next_execution |
| Form | A custom form is submitted. | submission_id, submitted_at, form_data |
A webhook's request body is under payload, so a body field is {{trigger:webhook.output.payload.userId}}, not {{trigger:webhook.output.userId}}.
Workflows and Error triggers
Both react to another workflow, which you pick when you add them. The Workflows trigger fires when that workflow finishes a cycle without a failed step. The Error trigger fires when a cycle of that workflow has a failed step, and hands you the failure details (errorMessage, failedSteps, and the step counts). A failing error-handling workflow does not set off other error handlers.
Integrations
The Integrations tile opens the app picker (Gmail, Slack, Notion, and hundreds more). Choosing an operation adds an integration step, keyed mcp:<name>. It calls that one operation with the credential you connected. Its parameters and output fields are those of the chosen operation, shown in the inspector. See Integrations.
AI
AI nodes call a model and use the agent: prefix. See Agents for models, tools, and budgets.
| Palette name | What it does | Ports | Main outputs |
|---|---|---|---|
| Agents | Reasons over a prompt and can call tools to produce a result. | None | response, tokens_used, tool_calls, iterations_used, model, provider |
| Guardrail | Checks content for PII, toxicity, or keywords, then passes or fails it. | pass, fail | passed, violations, details, sanitized |
| Classify | Routes the input to exactly one category by meaning. | category_N | selected_category, selected_category_index, confidence, reasoning, probabilities |
| Browser Agent | Drives a browser: navigates, fills forms, extracts structured data. | None | final_result, extracted_data, stop_reason, final_url, pages_visited, screenshots |
| Generate | Produces an image, video, audio, voice, or music clip from a prompt. | None | file, model, kind, provider, billed_quantity, billed_unit, billed_credits |
Generate
Pick an asset type and a Model. The model decides the format produced, which parameters are accepted (prompt, duration, aspect ratio, resolution, voice, input images, and so on), and what each run costs; the price is shown before you run. The result is always a file: output.file is a file reference you can pass whole to a later file parameter, and kind says what was produced. The same models are available in Studio.
Flow
Flow nodes route, repeat, parallelize, and join. For how branches, merges, and parallel items behave at run time, see Workflows.
| Palette name | What it does | Ports | Main outputs |
|---|---|---|---|
| If / else | Takes the first branch whose condition is true (exactly one). | if, elseif_N, else | selected_branch, selected_branch_index, skipped_branches, evaluations |
| Switch | Takes the first case that matches a value, or the default. | case_N, default | selected_branches, selected_case_index, skipped_branches, evaluations |
| Split | Runs the steps after it once per list item, in parallel. | None | items, item_count, split_id, spawn_reason, terminated |
| Aggregate | Collects the per-item results of a Split back into lists. | None | aggregated_count |
| While | Repeats a group of steps while a condition is true. | body, exit | iteration, maxIterations, terminated, selected_path, reason |
| User Approval | Pauses until a person approves, rejects, or the timeout passes. | approved, rejected, timeout | approval_context, selected_port, expires_at, required_approvals, delegated_channel |
| Transform | Computes new fields from expressions. | None | transformed, evaluations |
| Merge | Waits for every incoming branch, then continues once. | None | merged_branches, sources, merged_items, source_count, success_count |
| Fork | Runs every branch in parallel. | branch_N | branch_count, branches |
| Sub-Workflow | Triggers another workflow and waits for its result. | None | result, subWorkflowId, subRunId, success |
If / else and Switch
Both take exactly one path. If / else checks its conditions in order (if, then elseif_0, elseif_1, and so on) and falls back to else. Switch compares one value against its cases and falls back to default. Every path not taken is skipped. The evaluations output shows how each condition resolved, which is the fastest way to see why a branch was chosen.
The AI builder can also add an Option node (first true choice wins, ports choice_N). It is not in the palette, but it runs normally when a plan contains it.
Split
Give Split a list expression. Every step after it runs once per item, in parallel, and inside those steps {{core:<split>.output.current_item}} and current_index hold the item being processed. Those two fields exist only inside the split; they are not stored on the Split node itself.
- Max items defaults to 100. Items beyond the cap are dropped. It accepts an expression, which must resolve to a positive whole number or the node fails.
spawn_reasonisitems_spawned, orempty_listwhen there was nothing to process.terminatedis alwaystrue: Split finishes as soon as it has handed out the items.
Aggregate
Aggregate closes a Split: it waits for every item and returns one list per field you configure, plus aggregated_count.
While
While runs the steps on its bodyport, then evaluates its condition again. The last body step connects back to the node's iterate input. When the condition is false the loop leaves through exit. iteration starts at 0.
- Max iterations defaults to 10 and accepts 1 to 10,000 (or an expression that resolves to a positive whole number).
reasontells you how it ended:condition_false(normal),iterations_exhausted(no condition, so it ran the set number of times), ormax_iterations_reached.
User Approval
The run pauses and the approver sees the request in the app. The node continues on approved, rejected, or timeout. The timeout defaults to 24 hours. You can require several approvals and restrict who may decide by role.
- Approval context: text mixed with
{{...}}expressions, shown to the approver. The resolved text is also theapproval_contextoutput. - Continuation (only inside a Split, where each item gets its own request): After all items (the default) starts the next steps once every item has been decided. Per item (immediate) lets each decided item continue immediately; a Merge after it still waits for all items.
- Delegate via external channel: also sends the request to Telegram, Slack, Discord, WhatsApp, or Microsoft Teams with approve and reject buttons. Pick a Destination like a credential (the workspace default, a connected destination, or another chat by hand). You can set a message template, an image (for example an interface screenshot), custom button labels, and a list of allowed user IDs. The in-app decision keeps working in parallel. See Channels.
Merge and Fork
Fork starts every connected branch at once. Merge waits until every incoming branch has finished or been skipped, then continues once. Any node with several incoming edges waits the same way, and any node with several outgoing edges fans out the same way.
Transform
Each field you define is an expression. The results are under transformed, so a field named total is {{core:<label>.output.transformed.total}}. An object built in a Transform reaches later steps as text; when a later parameter needs a real object or list, build it in a Code node.
Sub-Workflow
Sub-Workflow fires a trigger in another workflow (the child), passes it an input, and waits for that child run to finish. Parameters: Workflow ID, Input mapping(one expression that resolves to the object to pass; empty forwards this workflow's trigger data), Timeout (seconds), and Max depth.
- The child needs a live run. The node never creates one. Pin a version of the child (which creates its run); an unpinned child uses its most recently started active run, whatever its version.
- Outputs are keyed by the child step's bare name. A child Transform named Step Result is read as
{{core:call.output.result.step_result.output.transformed.field}}, without acore:prefix beforestep_result. With the prefix the expression resolves to nothing, silently. successistruewhenever the child run finished, even if one of its nodes failed. Check the child's actual output before relying on it.- Timeout defaults to 300 seconds and is capped at 1,500. It only limits how long this node waits; the child keeps running. Max depth defaults to 5 (at most 10), and a workflow cannot call itself in a cycle.
Core
Core holds everything else. The tables below follow the palette, grouped by purpose. Detail entries for several of these nodes follow the tables.
Run control and replies
| Palette name | What it does | Main outputs |
|---|---|---|
| Exit | Ends the branch it sits on. Other branches keep running. | exited_at, reason, status |
| Stop on Error | Fails the whole run and cancels every branch. | error_message, error_code, stopped_at, status |
| Wait | Pauses for a duration, then continues on its own (see note). | waited_ms, status, started_at, completed_at, duration_ms, expires_at |
| Respond to Chat | Sends one message (a template) back to the chat that started the run. | message, sent_at, message_id |
| Respond to Webhook | Answers the HTTP caller of a Webhook trigger: status, content type, headers, body. | responded, statusCode, contentType |
| Interface | Shows a web page built from workflow data; can pause the run until the user continues. | interface_id, screenshot, pdf, video |
| Note | An annotation on the canvas. It never runs. | None |
HTTP, files, and media
| Palette name | What it does | Main outputs |
|---|---|---|
| HTTP Request | Calls any URL (see note). | success, status, statusText, data, headers, error |
| Download File | Fetches a file from an http or https URL (up to 50 MB) into storage. | file, source_url |
| Public Link | Turns a file into a public, time-limited signed URL (see note). | url, expires_at, ttl_minutes, file |
| Media | Processes audio and video files (see note). | file, duration_seconds, size_bytes, has_video, has_audio, video, audio |
| Data Input | Provides labeled text, file, and image inputs; each is output under its own label. | One field per input label |
| Convert to File | Writes items to a CSV, XLSX, JSON, or TXT file. | file, format, row_count, success |
| Extract From File | Reads a file into items or text (see note). | items, format, rowCount, columns, mode, total_chunks |
| Compression | Compresses or decompresses zip, gzip, or deflate data. | result, file, operation, format, success |
Data
| Palette name | What it does | Main outputs |
|---|---|---|
| Filter | Keeps the items that match conditions (equals, contains, greater than, is empty, and more). | items, rejected_items, count, rejected_count, original_count |
| Sort | Orders items by a field. | sorted_items, count |
| Limit | Keeps the first or last N items. | items, count, original_count |
| Remove Duplicates | Drops items that repeat on the chosen fields. | items, original_count, deduplicated_count, removed_count |
| Summarize | Count, sum, average, min, max, count distinct, or concatenate, optionally grouped by fields. | groups, total_groups, total_items, aggregation_count |
| Compare Datasets | Compares two lists on key fields. | matched, onlyInA, onlyInB, matchedCount, totalA, totalB |
| Set / Edit Fields | Assigns fields with a type (string, number, boolean, JSON). | fields, output, keep_only_set, count |
| HTML Extract | Pulls structured data out of HTML with CSS selectors. | items, count, matched_root, errors |
| XML | Converts XML to JSON or JSON to XML. | result, operation, success |
Code, messaging, and utilities
| Palette name | What it does | Main outputs |
|---|---|---|
| Code | Runs JavaScript, Python, TypeScript, or Bash in a sandbox (see note). | result, stdout, stderr, exitCode, success |
| Send Email | Sends an email with your SMTP credential. | sent, messageId, recipients, subject, success |
| Email Inbox | Reads a mailbox over IMAP, or marks read or unread, flags, moves, or deletes a message. | messages, count, folders, action, success |
| RSS | Fetches and parses an RSS or Atom feed. | items, channel, itemCount, feedFormat, success |
| Crypto / JWT | Hash, HMAC sign and verify, encrypt and decrypt, create, decode, and verify JWTs, Base64, UUIDs, and random secrets. | result, operation |
| Date & Time | Parse, format, convert time zones, add, subtract, compute differences, extract parts, or get the current time. | result, operation |
| Task | Creates, reads, updates, deletes, or lists agent tasks. | task, task_id, tasks, count, success |
Remote systems
| Palette name | What it does | Main outputs |
|---|---|---|
| SSH | Runs a command on a remote server. | success, exit_code, stdout, stderr, duration_ms |
| SFTP | Uploads, downloads (up to 50 MB), lists, deletes, renames files, or creates folders. | success, operation, remote_path, files, file, new_path |
| Database | Runs select, insert, update, delete, or raw SQL on PostgreSQL, MySQL, or MSSQL (up to 10,000 rows). | success, rows, columns, row_count, affected_rows |
Exit and Stop on Error
Exit ends only its own branch; the run can still succeed. Its reason defaults to “Branch exited” and status is exited. Stop on Error fails the whole run with your error message and code.
Wait
In the canvas you enter the duration in milliseconds, up to 10 minutes. A wait of 3,000 ms or less runs inline. A longer wait pauses the run and resumes it on a timer.
HTTP Request
Methods: GET, POST, PUT, PATCH, DELETE, HEAD, OPTIONS. Authentication: none, basic, bearer, API key, or a custom header. An optional timeout is available.
Download File, Public Link, and file references
Download File follows redirects (each hop is checked again) and returns file, a file reference with path, name, mimeType, and size. Pass the whole reference to a file parameter with {{core:<label>.output.file}}. See Files & storage.
Public Link signs a file from an earlier node into a public URL that anyone can open until it expires, for APIs that pull media from a URL (Instagram, TikTok) instead of accepting an upload. Link lifetime is 5 to 10,080 minutes (7 days), 240 by default. Disposition is inline (shown in the browser) or attachment (download prompt). A link cannot be revoked before it expires.
Media
Operations: Probe (read duration, streams, codecs), Mux audio (one audio track onto one video), Mix (up to 8 audio tracks, optionally onto a video), Extract audio, Concat (up to 8 videos back to back, with cut or crossfade), Frame (one still image, the middle by default), Overlay (burn an image onto a video), and Burn captions.
- Every file parameter must be one whole expression that resolves to a file reference, such as
{{core:download.output.file}}. - The Concat clip list is fixed in the node (one entry per clip); it cannot come from a single list expression.
- The node fails when the media renderer is not available on your installation.
Convert to File and Extract From File
Convert to File writes csv, xlsx, json, or txt. Extract From File parses csv, xlsx, and json into items, or extracts the text of a pdf, html, docx, txt, csv, or json file, optionally split into chunks (recursive or by separator, with a chunk size and overlap). For XML, use the XML node.
Code
Upstream results arrive in $input (JavaScript and TypeScript), _input (Python), or INPUT(Bash), keyed by each earlier node's normalized name: a file from Download Demo Video is $input.download_demo_video.file, not $input.file. Return data by assigning $output (or _output in Python). The timeout defaults to 10 seconds, up to 120.
What you return is stored under result, so downstream you read {{core:<label>.output.result.<field>}}. Values keep their types, which makes Code the right place to build objects, lists, or file references for later steps.
{{core:normalize.output.result.total}} the "total" field of the returned object
{{core:normalize.output.stdout}} anything the script printedTables
The Tables section of Core reads and writes the built-in tables. These nodes use the table: prefix. See Tables & data for columns and query options.
| Palette name | What it does | Main outputs |
|---|---|---|
| Create Row | Inserts one or more rows. | row_id, created_at, inserted_count, inserted_values, warnings |
| Create Column | Adds columns to a table. | createdColumns |
| Get Row | Returns matching rows as one output. | rows, row_count, has_more, offset |
| Update Row | Updates the rows that match a condition. | updated_count, rows_affected, updated_at, warnings |
| Delete Row | Deletes the rows that match a condition (a condition is required). | deleted_count, rows_affected, deleted_at |
| Find Rows | Queries rows into a list. | items, item_count, total_before_limit, max_items, has_more, exit_reason |
Find Rows
Find Rows returns its matches as one list in items. It does not run the following steps once per row. To process each row, add a Split on {{table:<label>.output.items}}. It keeps 100 rows by default. You can set a higher limit, but one read returns at most 500 rows, so a limit above 500 behaves like 500. With the default limit, has_more tells you whether rows were left out; with a limit you set, compare item_count to that limit instead. exit_reason is items_found or empty_result.