Skip to main content
DocsCode Node

Code Node

Run a short piece of JavaScript inline in a workflow. Perfect for formatting values, combining variables, calling a public API, or computing a quick calculation without setting up a full integration action.

Code Node vs Custom Integration Action

Staffify gives you two ways to run custom logic during a call. Pick the one that matches your use case.

Code NodeCustom Integration Action
RunsJavaScript in Staffify sandboxHTTP request to your server
RequiresNothing — runs directlyYour own API endpoint
Best forFormatting, calculations, quick public API lookupsBusiness writes, authenticated integrations, CRM sync
Max code size5,000 charactersN/A (runs on your server)
SecretsNot safe — see security sectionManaged by your backend

Rule of thumb: reach for a Code Node when the work is lightweight — string formatting, arithmetic, or a read-only call to a public endpoint. For everything that touches your production systems, use a Custom Integration Action.

Adding a Code Node to your workflow

  1. In the workflow builder, drag Code from the left palette onto the canvas.
  2. Click the node to open its configuration panel on the right.
  3. Write JavaScript in the editor. You have access to the caller's workflow variables via dv, call metadata via metadata, and fetch() for HTTP requests.
  4. Return a JSON object with the values you want to keep.
  5. In Store fields as variables, list the fields from your returned object that should become workflow variables usable in later nodes.
  6. (Optional) Click Run Code in the test panel to try it with mock variable values before saving.

The JavaScript environment

Your code runs in an isolated V8 heap with a small set of globals. Standard built-ins like Math, JSON, Date,Array, and String all work. Top-level await is supported.

dv — workflow variables

Every workflow variable collected earlier in the flow is available under dv. Values are always strings, so use parseFloat or parseInt when you need a number.

const name = dv.caller_name;           // "Jan de Vries"
const orderId = dv.order_id;          // "78542"
const total = parseFloat(dv.amount);  // convert to number

metadata — call metadata

Any metadata attached to the session when the call started is available under metadata. Typical values include customer IDs or priority levels passed in from the API that initiated the call.

fetch(url) — HTTP requests

Make HTTP requests to public APIs. Works like the standard Fetch API but is limited to protect the sandbox from abuse (see limits below).

// GET request
const response = await fetch("https://api.example.com/data");
const data = await response.json();

// POST request
const response = await fetch("https://api.example.com/submit", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ name: dv.caller_name })
});

console.log()

Log values for debugging. Logs appear in the test panel and are stored in the execution log for every real call.

Limits

ResourceLimitWhat happens when exceeded
Code size5,000 charactersNode fails to save
Result size15,000 characters (serialized JSON)Result is discarded, node marked failed
Wall-clock timeout5–60 seconds (default 30)Execution killed, node marked failed
Memory32 MB per invocationExecution killed with an OOM error
fetch() calls5 per invocationSixth call throws
fetch() body1 MB responseResponse truncated, node fails
fetch() timeout10 seconds per callRequest aborted
Rate limit100 requests per hour per host per tenantFurther calls throw

Storing values as variables

The Store fields as variables table lets you extract values from your returned JSON and save them as workflow variables. The field column accepts dot notation and array indexing.

Field pathExampleExtracts
Top-levelstatusresult.status
Nesteddata.order.idresult.data.order.id
Array elementitems[0].nameFirst item's name
Nested arrayorders[2].items[0]First item of the third order

If a path doesn't resolve, the variable is silently skipped — the workflow does not fail on missing optional fields.

Node settings

  • Speak during execution: choose whether the agent stays silent (Off), lets the LLM improvise a short filler like “let me look that up for you” (Prompt), or speaks an exact sentence you provide (Static text). Useful when your code makes an API call that takes a few seconds.
  • Play typing sound: plays a subtle typing loop while the code runs, signaling activity to the caller.
  • Wait for result: when enabled the workflow waits for the code to finish before continuing. Turn off for fire-and-forget notifications where you don't need the result.
  • Execution timeout: slider between 5 and 60 seconds. Default 30. Long-running code is killed and the execution logged as timeout.

Security and what NOT to do

Do not use Code Nodes for secrets. Both dv and metadata are stored in plaintext in every call log and API response. Anything you put there is visible to anyone with access to your call history.

  • No secrets in variables. API keys, database credentials, session tokens — none of these belong in workflow variables. Use a Custom Integration Action instead, where the auth stays server-side.
  • No production writes. The Code Node is designed for lightweight logic. Writing to your CRM, taking payments, or updating customer records should go through an Integration Action with proper audit logging and idempotency.
  • Fetch is limited by design. Requests to private IP ranges (10.x, 192.168.x, 127.0.0.1) and known internal hostnames are blocked. AWS/GCP metadata endpoints (169.254.169.254) are blocked. Redirects are re-checked at every hop.
  • No filesystem, no npm packages. The sandbox exposes only the standard JavaScript built-ins plus the globals listed above. require and import are not available.

Examples

Format a customer's full name

// Combine first + last + tussenvoegsel into a single string
const parts = [dv.first_name, dv.tussenvoegsel, dv.last_name]
  .filter(Boolean)
  .join(" ");
return { full_name: parts };

Calculate a total with VAT

const nights = parseInt(dv.nights, 10);
const rate = parseFloat(dv.rate);
const subtotal = nights * rate;
const vat = subtotal * 0.21;
return {
  subtotal_eur: subtotal.toFixed(2),
  vat_eur: vat.toFixed(2),
  total_eur: (subtotal + vat).toFixed(2)
};

Look up an address from postcode + house number

const response = await fetch(
  `https://postcode.tech/api/v1/postcode?postcode=${encodeURIComponent(dv.postcode)}&number=${encodeURIComponent(dv.house_number)}`
);
const data = await response.json();
return {
  street: data.street,
  city: data.city,
  province: data.province
};

Decide routing based on customer tier

const tier = (dv.customer_tier || "standard").toLowerCase();
if (tier === "premium") {
  return { route: "priority_queue", greeting: "premium" };
} else if (tier === "vip") {
  return { route: "dedicated_agent", greeting: "vip" };
}
return { route: "general_queue", greeting: "standard" };

Handling failures

When a Code Node fails (timeout, thrown error, out of memory, blocked fetch, etc.), the workflow does not halt. Instead a special variable is set that downstream nodes can branch on:

code_error — set to a short description of what went wrong

You can wire a Condition node right after the Code Node with a check on {{code_error}} is not empty to send the call down an error-handling path (e.g. a graceful apology + transfer).

Wrap risky code in a try / catch when you want to handle errors yourself without triggering the workflow-level fallback:

try {
  const r = await fetch("https://api.example.com/thing/" + dv.id);
  const data = await r.json();
  return { status: "ok", value: data.value };
} catch (err) {
  return { status: "failed", reason: String(err) };
}

Execution history

Every Code Node invocation — real calls and Run Code tests — is logged to your account. Each row records the outcome status, duration, error message (if any), number of fetch() calls made, and the size of the returned result. This is intended for debugging and abuse monitoring.

The actual JavaScript source is not stored in the log — it lives on the workflow definition — so we don't duplicate it.

Code Node - Run JavaScript in a workflow