Skip to content

Workflow node reference - every ready-made step ​

What it is for ​

A node is a ready-made step you drop into a stage instead of writing code. Each runs as an ordinary service task. It calls the platform's own endpoints as the configured user, so permissions, tenancy and audit apply exactly as for a person.

Every node returns its answer under the task key: ${context.<taskKey>.<field>}. Values from the workflow are written ${context.name}. The designer checks required fields and shows a problem on the node before you can publish.

Actions ​

Set variables - variable.set ​

Names values for later steps.

json
{"taskKey": "set-1", "stage": "start", "taskType": "variable.set", "kind": "service",
 "payload": {"values": {"limit": 500, "owner": "${context.managerEmail}"}}}

Later steps read ${context.limit}.

Create, update, delete, get record - record.create, record.update, record.delete, record.get ​

One record through the entity endpoints.

json
{"taskKey": "create-1", "stage": "approved", "taskType": "record.create", "kind": "service",
 "payload": {"entity": "loan_payment", "values": {"loan": "${context.recordId}", "status": "OPEN"}}}

Fields: entity, id (update, delete, get), values (create, update; update changes only the listed fields). The new record comes back as ${context.create-1.id}.

Export to CSV - data.exportCsv ​

Turns a list of records into CSV text: ${context.<key>.csv} and rowCount. Fields: rows, columns (comma separated, optional; empty means every field of the first row). Cells that begin with =, +, - or @ get a leading apostrophe so a spreadsheet cannot run them as a formula.

Generate document - document.generate ​

Makes a PDF, HTML or text file.

  • From a print template (printTemplate): a designed, branded PDF filled with real data. Give recordId to print a record and its linked child rows, or give data and childRows to print values the workflow holds. Not both.
  • From text (template): a text with placeholders, shown below. A missing value is an error. HTML output escapes values. A text template saved as PDF is a plain-text document.
text
Dear (name), (name | fallback)
Repeat a block for every item in a list:  (#each list) (@index). (item.x) (/each)
Keep a block only when a value exists:    (#if x) ... (/if)

In the real template each placeholder is written with double curly braces instead of the round brackets used here.

  • Where it goes: with cabinetId (and optional folderId) the file is stored in document management and its id returned; attachEntityType and attachEntityId also attach it to a record. Without a cabinet the content comes back inside the workflow as contentBase64 (up to 256 KB).
json
{"taskKey": "letter", "stage": "approved", "taskType": "document.generate", "kind": "service",
 "payload": {"printTemplate": "offer-letter", "recordId": "${context.recordId}", "cabinetId": 3, "filename": "offer-letter",
             "attachEntityType": "candidate", "attachEntityId": "${context.recordId}"}}

Designed PDFs need PDF export switched on and a browser engine available to the backend. Rendering takes a few seconds, so give the worker a longer task timeout.

Run integration - integration.run ​

Runs a connector or a flow from the integration platform. Fields: kind (connector or flow), key, input (values), timeoutSeconds. The integration platform owns addresses and credentials, and the call is made idempotent per task.

HTTP - http ​

Calls an address you give. Prefer Run integration, which keeps addresses and secrets out of the workflow.

Logic ​

Calculate - calculate ​

Arithmetic without scripting. + - * / % ( ) and round abs min max ceil floor, with exact decimals. Later formulas may use earlier results.

json
"payload": {"variables": {"qty": "${context.quantity}", "price": "${context.unitPrice}"},
            "expressions": {"total": "qty * price", "tax": "round(total * 0.18, 2)"}}

Script - script ​

A few lines of logic, safely. name = expression per line over the node's variables. Numbers, text, true/false, lists and records; + - * / %, comparisons, && || !, cond ? a : b, a.b, a[0]; and len upper lower trim substring contains startsWith endsWith replace split join coalesce isEmpty toNumber toString round abs min max ceil floor sum count. It is parsed and evaluated, never executed as code: no loops, no files, no network, no clock, at most 5000 characters.

Code (JavaScript) - code.js ​

Real JavaScript for logic that needs more. Write a function body that gets input and console and returns a value. A returned object's fields join the workflow's data; anything else comes back as result. console.log lines appear in the run history. Limits: 20000 characters, a time limit of 5 seconds by default (at most 20), 256 KB in, 512 KB out.

It runs in a separate, memory-limited process with an empty environment and no access to Java classes, files, network or the database, and the process is killed at the deadline. This is strong isolation but not an operating-system jail, so for untrusted multi-tenant use run workers in containers without network access.

For each - loop.foreach ​

Starts a workflow once per item of a list.

FieldMeaning
itemsThe list, e.g. ${context.lines}
workflowThe workflow to start for each item
itemNameName of the item inside the child (default item; index and count are also provided)
waitWhen on, finish only when every started run has finished (checked every pollSeconds, default 15)
failOnChildFailureWhen waiting, fail if any run fails (default on). The result also carries completed, failed, cancelled
maxWaitMinutesGive up waiting after this long (default 1440)

Starting is idempotent: a retry never starts the same child twice.

Notifications ​

All of these send through a named integration connector, so no address or secret is stored in the workflow.

NodetaskTypeFields
Send emailnotify.emailconnector, to, subject, message
Send SMSnotify.smsconnector, to, message
Slack messagenotify.slackconnector, channel (optional), message
Teams messagenotify.teamsconnector, channel (optional), message
In-app notificationnotify.inappto (user id, comma list or list), subject (optional), message, category

In-app notifications go to the person's notification inbox and are idempotent per task.

Timers ​

NodetaskTypeFields
Delaytimer.delaydays, hours, minutes, seconds (at least one)
Wait untiltimer.untilat: an ISO date-time, a date, or a value from the workflow

A timer does not hold a thread. The task is queued to become due later, so waiting survives restarts and scaling.

AI nodes ​

Each does one bounded thing and returns typed fields; ordinary conditions and approvals decide what happens next. They call the AI platform's public endpoints as the configured user.

NodetaskTypeWhat it doesKey fields
Run a promptai.promptRuns a library promptcode, values, version or label, profileCode
Classifyai.classifyRuns a prompt that answers in JSON and returns its fieldssame as Run a prompt
Retrieveai.retrieveSearches a knowledge baseknowledgeBase, query, mode, topK, threshold
Answer from knowledgeai.ragRuns a RAG pipelinepipelineCode, question, version or label
Run an agentai.agentRuns an agentagentCode, intent (what it should do), timeoutSeconds
Guardrailai.guardrailLocal checks for personal data and prompt injection (the defaults), blocked terms and length. No model calltext, checks, blockedTerms, maxLength

See Put AI inside a business workflow.

Engagement nodes ​

engage.message, engage.voice, engage.wait-reply and engage.mark are the steps Engagement journeys compile to. See Reach customers with journeys.

Where next ​