Skip to main content
Code node executes JavaScript code when the agent enters it. Unlike custom functions, code nodes run directly in Retell’s sandbox — no external server needed. The node is not intended for having a conversation with the user, but the agent can still talk while code is running if needed.
Code node on the conversation flow canvas

Code Node vs Custom Function

Code NodeCustom Function
RunsJavaScript in Retell’s sandboxHTTP request to your server
RequiresNothing — runs directlyYour own API endpoint
Best forData transformation, simple API calls, logic & calculationsComplex integrations, accessing internal systems
Max code size5,000 charactersN/A (runs on your server)

Write Your Code

1

Add a Code Node

Click the Code node from the left sidebar to add it to the canvas.
Left sidebar showing the Code node option
2

Open the code editor

Click Open on the code node to launch the code editor.
3

Write JavaScript

Write your JavaScript code in the editor. You have access to dynamic variables, call metadata, and the fetch function for HTTP requests. See JavaScript Environment below for details.
Code editor with JavaScript code and configuration options
// Example: look up an order and return the status
const response = await fetch("https://api.example.com/orders/" + dv.order_id);
const data = await response.json();
return { status: data.status, estimated_delivery: data.delivery_date };
4

Set response variables (optional)

Use Store Fields as Variables to extract values from your code’s return value and save them as dynamic variables. Specify a variable name and the JSON path to the value.For example, if your code returns { "status": "shipped", "estimated_delivery": "March 25" }:
Variable NameJSON PathExtracted Value
order_statusstatus"shipped"
delivery_dateestimated_delivery"March 25"
These variables can then be referenced as {{order_status}} and {{delivery_date}} in other nodes.
5

Test your code

Click Run Code at the bottom of the editor to test. Use the Dynamic Variables dropdown in the editor to set test values for your variables (e.g., give customer_name a value of “John Doe”) — these values are only used during testing and won’t affect your live agent. The output panel will show the result and any console.log() output.
Code editor showing test output after clicking Run Code

JavaScript Environment

Your code runs in a JavaScript sandbox with the following globals available. The code editor provides autocomplete — as you type, it will suggest available globals, dynamic variable names, and built-in functions.

dv — Dynamic Variables

Access your agent’s dynamic variables as properties on the dv object. All values are strings.
const name = dv.customer_name;       // "John Doe"
const orderId = dv.order_id;         // "78542"
const total = parseFloat(dv.amount); // Convert to number if needed

metadata — Call Metadata

Access metadata passed when the call was created via the API. This is the same object you pass in the metadata field of the Create Call API.
const customerId = metadata.customer_id;
const priority = metadata.priority_level;

fetch(url) — HTTP Requests

Make HTTP requests to external APIs. Works like the standard Fetch API.
// 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.customer_name })
});

console.log() — Debugging

Log output for debugging. Logs appear in the test output panel when using Run Code, and are also available in call logs.
console.log("Customer:", dv.customer_name);
console.log("API response:", JSON.stringify(data));
  • Your code can return any value (object, string, number) or return nothing at all.
  • Standard JavaScript built-ins are available: Math, JSON, Date, Array, Object, String methods, etc.
  • External packages (require, import) are not available. Use fetch() for external integrations.
  • Code is limited to 5,000 characters.

Examples

Format data from dynamic variables

// Combine and format customer info
const fullName = dv.first_name + " " + dv.last_name;
const summary = `Customer ${fullName} (ID: ${dv.customer_id}) requested a callback.`;
return { full_name: fullName, summary: summary };

Fetch data from an external API

// Look up order status from your API
const response = await fetch("https://api.example.com/orders/" + dv.order_id, {
  headers: { "Authorization": "Bearer " + dv.api_token }
});
const order = await response.json();
return {
  status: order.status,
  items: order.items.length,
  total: "$" + order.total.toFixed(2)
};

Conditional logic with API call

// Route based on customer tier
const response = await fetch("https://api.example.com/customers/" + dv.customer_id);
const customer = await response.json();

if (customer.tier === "premium") {
  return { action: "priority_support", wait_time: "0 minutes" };
} else if (customer.tier === "standard") {
  return { action: "standard_queue", wait_time: "5 minutes" };
} else {
  return { action: "general_queue", wait_time: "10 minutes" };
}

Response Variables

Response variables let you extract specific values from your code’s return value and store them as dynamic variables for use in other nodes. Specify each variable as a name and a JSON path using dot notation:
Path SyntaxExampleExtracts
Top-level fieldstatusresult.status
Nested fielddata.order.idresult.data.order.id
Array elementitems[0].nameFirst item’s name
If a path doesn’t exist in the return value, the variable is skipped (no error).

When Can Transition Happen

  • If Wait for Result is turned off:
    • If Speak During Execution is on, the agent transitions once done talking
    • If Speak During Execution is off, the agent transitions immediately after code starts running
    • If the user interrupts the agent, transition can happen once the user is done speaking
  • If Wait for Result is turned on:
    • If Speak During Execution is on, the agent transitions once code finishes and agent is done talking
    • If Speak During Execution is off, the agent transitions once code finishes
    • If the user interrupts the agent, transition can happen once code finishes and user is done speaking
Since the code node considers the code result for transition timing, you can write transition conditions based on the code result or the extracted dynamic variables.

Node Settings

  • Speak During Execution: When enabled, the agent says something while the code runs (e.g., “Let me check that for you.”). Choose between Prompt (LLM generates the message) or Static Text (exact text you provide).
  • Wait for Result: When enabled, the agent waits for the code to finish before transitioning. This guarantees that when you reach the next node, the result and extracted variables are ready.
  • Timeout: How long the code can run before timing out. Range: 5–60 seconds. Default: 30 seconds.
  • Global Node: Read more at Global Node.
  • Block Interruptions: When enabled, the agent will not be interrupted by the user when speaking.
  • LLM: Choose a different model for this node. Used for speak during execution message generation if set to Prompt.
  • Fine-tuning Examples: Can finetune transition. Read more at Finetune Examples.

FAQ

No. The code runs in a lightweight JavaScript sandbox without access to require or import. You can use all standard JavaScript built-ins (Math, JSON, Date, Array methods, etc.) and the fetch() function for external API calls.
If your code exceeds the configured timeout (default 30 seconds), it will be stopped and treated as a failed execution. The result will contain a timeout error message. You can adjust the timeout in Node Settings (5–60 seconds).
If your code throws an error or crashes, the execution is marked as failed and the error message is returned as the result. Response variables will not be extracted. You can use try/catch in your code to handle errors gracefully.
Yes. The fetch() function is async, so you can use await to wait for HTTP responses. Top-level await is supported.
Yes, the result is capped at 15,000 characters to prevent overloading the LLM context.