Skip to main content
A custom function lets your conversation flow 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 where the flow goes next.
Custom functions run inside a function node. If the logic is self-contained and doesn’t need your server, a code node runs it in a sandbox with no endpoint to host.

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 flow branches to read it back or to escalate if the order can’t be found.

Create a custom function

When the function is called, Retell sends a request (POST, GET, PUT, PATCH, or DELETE) to your URL with the function name and arguments. You can add headers and query parameters, and extract values from the response.
1

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 configuration 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
2

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.
3

Add the endpoint URL

Enter the URL Retell calls to run the function. 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.
4

Set a timeout (optional)

Set how long Retell waits for your endpoint to respond, in milliseconds. 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.
5

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
6

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.
7

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
8

Set response variables (optional)

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

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 the flow. (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 the flow around the function node. Make the description specific about what the function does and when to use it, and make sure the flow reaches the node under the right conditions. 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 flow can speak or branch 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 the flow. 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 any waiting or follow-up message for that call is 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.