Skip to main content
A custom function lets your agent call your own API during a live call, then use the response to keep the conversation going. Use it to look up an order, check an account, create a ticket, or trigger any action in your backend that the agent can’t do on its own.

When to use a custom function

Reach for a custom function whenever the agent needs live data from your systems, or has to take an action there, in the middle of a call:
  • Look up real-time data — order status, appointment slots, account details, shipment tracking.
  • Take an action in your backend — create a support ticket, update a record, send a confirmation.
  • Branch on your own logic — call an endpoint that decides what the agent should do next.
If the logic is self-contained and doesn’t need your server — a calculation, reading a dynamic variable, or a request to a public API — a code tool runs it in a sandbox with no endpoint to host. For common built-in actions like transferring or ending a call, use the prebuilt functions instead.

Example: order status lookup

A retail support agent needs to tell callers where their order is. You add a get_order_status custom function pointed at https://api.yourstore.com/orders. When a caller gives their order number, the agent calls the function with that number, your API returns the status and delivery date, and the agent reads it back: “Your order shipped yesterday and arrives Thursday.” No human has to look it up.

Create a custom function

The agent calls a custom function whenever your prompt and the function’s description tell it to. When it does, Retell sends a request to your URL with the function’s arguments and waits for your response before continuing.
1

Add a custom function

In your agent, open the Functions section, click + Add, and choose Custom Function.
Functions section with the Add menu open and Custom Function listed among the tool options
2

Name and describe it

Give the function a unique name using letters and underscores (for example get_order_status), and a clear description. The agent reads the description to decide when to call the function, so be specific about what it does and when to use it.
Custom function modal showing name, description, HTTP method, endpoint URL, timeout, and headers fields
For example:
  • Name: get_user_details
  • Description: Get user details based on name and age
3

Choose the HTTP method

Select the method Retell uses to call your endpoint: GET, POST, PUT, PATCH, or DELETE. It defaults to POST.Retell sends a JSON body only for POST, PUT, and PATCH. GET and DELETE carry data as query parameters only.
4

Add the endpoint URL

Enter the URL Retell calls to run the function, in the API Endpoint field next to the method selector. It must be a valid, publicly reachable URL. For security, Retell blocks requests to localhost, private IP ranges, and cloud metadata addresses, so to test against a local server, expose it first with a tunneling service like ngrok.
5

Set a timeout (optional)

Set how long Retell waits for your endpoint to respond, in milliseconds (labeled Timeout (ms) in the dashboard). It defaults to 120000 (2 minutes). If your endpoint doesn’t respond in time, the request fails and the agent receives the error message (for example, a timeout error) to act on. Retell does not retry a custom function, so keep the endpoint fast and handle any retries on your side.
6

Set request headers (optional)

Define custom headers to include with the request. Header values can be static or include dynamic variables, such as an auth token you pass in as {{token}}.
Request headers configuration with an Authorization header set to a dynamic variable
7

Set query parameters (optional)

Define query parameters as key/value pairs that Retell appends to the endpoint URL. Values are applied directly and can include dynamic variables. Query parameters are never filled in by the LLM — for LLM-supplied values, use the request body parameters below.
8

Define parameters

For POST, PATCH, and PUT requests, define the parameters the agent sends in the request body, using either JSON schema or the form editor. As with query parameters, a property with a description is filled in by the LLM, while a property with a const value is applied directly.Payload: args onlyWhen Payload: args only is on, the request body is just the function’s arguments at the top level, with no wrapper. When it’s off, the body follows the request spec below (name, call, and args).
Turn this on when your endpoint expects a flat JSON body that matches your parameter object exactly, with no outer wrapper.
Example parameter schema:
Example form editor:
Form editor for defining function parameters with name, type, and required columns
9

Set response variables (optional)

In the Store Fields as Variables section, extract values from the JSON response and save them as dynamic variables to use later in the conversation.Point each variable at a field in the response using dot notation, with array indexing where needed — for example user.name or data.items[0].id. This works only when your endpoint returns a JSON object.For example, from this response you could extract the user’s name and reference it later as {{user_name}}:
Response variable mapping that saves a field from the API response to a dynamic variable
10

Configure speech behavior

Control what the agent does while the function runs and after it returns.
  • Talk While Waiting (off by default) — the agent says something each time the function is called, to fill the silence while it waits, like “Let me look that up for you.” Choose Prompt to have the LLM generate the line, or Static Sentence to speak a fixed message you write. Turn it on for user-facing lookups; leave it off for background tasks like attaching a note.
  • Talk After Action Completed (on by default) — the agent keeps going after the function returns, without waiting for the user, so it can read back the result or call another function. Leave it on for almost everything; turn it off only for fire-and-forget tasks like pressing a digit, where you don’t expect the agent to say anything next.
If the user speaks while the function is running, the agent turns to answer them instead — the Talk While Waiting and Talk After Action Completed messages for that call are skipped or cut off, like any interrupted agent turn. The request to your endpoint still runs to completion — see the FAQ below.
11

Add prompt guidance

Tell the agent in your prompt exactly when to call the function. For example:

Troubleshooting

If the function won’t save, the parameters are usually invalid. The most common mistake is leaving "type": "object" off the top level of the JSON schema. Click one of the built-in examples and adjust from there.

Request and response spec

When the function is called, Retell sends a request to your endpoint with the following spec. Request
  • Headers
    • X-Retell-Signature: an HMAC-SHA256 signature of the request body, used to verify the request came from Retell. See Verify the request is from Retell below.
    • Content-Type: application/json (for POST, PUT, and PATCH).
  • Body (JSON, for POST, PUT, and PATCH only)
    • name: the name of the custom function.
    • call: the call object, for context about the call. It includes the transcript up to the moment the request is sent. See Get Call for the full object.
    • args: the function’s arguments, as a JSON object.
When Payload: args only is on, the body is just the arguments object — no name, call, or args wrapper. Parse the parameters from the top level, and run signature verification against that same body string.
The request times out after the timeout you set, or 2 minutes by default. Custom functions are not retried — if the request fails or times out, the agent receives the error message (such as the HTTP status or a timeout error) and continues based on your prompt. (This differs from event webhooks, which Retell does retry.) Response Return a status code between 200 and 299 to signal success. The response body can be a string, buffer, JSON object, or blob — all are converted to a string before being sent to the agent’s LLM. Only a JSON object response can populate response variables.
The function result is capped at 15,000 characters by default to avoid overloading the LLM’s context window. Contact support if you need a higher limit.

Verify the request is from Retell

To confirm a request came from Retell, verify the X-Retell-Signature header against the raw request body using your Retell API key. For GET and DELETE requests the body is empty, so pass an empty string to the verify function.
You can also restrict your server to Retell’s outbound IP address: 100.20.5.228.

FAQ

The agent decides when to call a function from its name, description, and your prompt. Make the description specific about what the function does and when to use it, and add an explicit instruction in the prompt (for example, “When the user gives an order number, call get_order_status”). Vague descriptions are the most common reason a function never fires.
Unless Payload: args only is on, the request body includes a call object with details like the call ID, agent ID, metadata, dynamic variables, and the transcript up to the moment the function is called. Use it for context — for example, to look up the caller by their metadata or a dynamic variable.
Return it in the response body. Everything you return is converted to a string and handed to the agent’s LLM, so the agent can speak or act on it right away. To reuse a specific value later in the call, map it to a dynamic variable with the response variables setting.
No. Unlike event webhooks, custom functions are not retried. If the request fails or times out, the agent receives the error message (such as the HTTP status or a timeout error) and continues based on your prompt. Keep your endpoint fast, and handle retries on your own side if you need them.
The agent handles it like any interruption: it turns to answer the user, and the Talk While Waiting and Talk After Action Completed messages for that call are skipped. The request to your endpoint is not cancelled, though — it runs to completion (up to the timeout), so any action it takes still happens and any response variables it returns are still saved. The result stays in the transcript, so the agent can still bring it up on a later turn; it just won’t read it back right at that moment. Because the request still reaches your endpoint, make side-effecting actions like creating a ticket or charging a card idempotent so a repeat call is safe.
Verify against the raw request body, not a re-serialized version. JSON.stringify(req.body) can reorder keys or change whitespace, which breaks the signature. Read the raw body (for example, with express.raw) and pass that exact string to the verify function.
No. Retell blocks requests to localhost, private IP ranges, and cloud metadata addresses to prevent server-side request forgery. Your endpoint must be publicly reachable — to test a local server, expose it with a tunneling service like ngrok.
Yes. The function result is capped at 15,000 characters by default before it reaches the LLM. Return only what the agent needs, and contact support if you need a higher limit.