Retell AI Custom Functions: How to Let Your Voice Agent Check Calendars, Look Up Customers and Take Real Actions (2026)
TL;DR: A custom function in Retell AI is a tool your agent can call in the middle of a conversation. You describe the function (name, what it does, which arguments it needs), Retell's model decides when to call it, and Retell sends a request to your endpoint, usually an n8n webhook or a small API. Whatever you return comes back to the agent, which then keeps talking. Custom functions are what turn a voice agent from a polite talker into something that books jobs, checks order status and updates a CRM. The hard part is not wiring them up. It is designing them so they are fast, hard to misuse, and fail gracefully on a live call. I build production voice agents for US clients on Retell, n8n, GoHighLevel and Twilio, and we run VoiceDash, the white-label client portal agencies hand their clients. This is how I design custom functions in real builds.
Every agency hits the same wall. The demo agent sounds great, then the client asks "can it actually book the appointment?" or "can it tell the caller if their technician is on the way?" The answer is yes, through functions. But a function that works on your test call and a function that holds up across thousands of real calls are two different things.
What a custom function actually is
You define a function inside your Retell agent with four things:
- A name, like
check_availabilityorlookup_customer - A description that tells the model when to use it
- A parameter schema listing the arguments the model must collect first, such as a date or a phone number
- A URL where Retell sends the request when the function is called
During the call, when the model decides it needs the function, it fills in the arguments from the conversation, Retell sends them to your URL, your endpoint does the work and returns a result, and the agent continues with that result in context.
Retell also ships built-in functions for common actions, such as ending the call and transferring to a human, plus calendar integrations. The exact list changes as Retell ships updates, so check the current docs before you build something custom that already exists. For transfers specifically, read voice AI call transfer to human.
The functions I build most often
Across niches, the same handful show up again and again:
| Function | What it does | Typical backend |
|---|---|---|
check_availability |
Returns open slots for a date range | Client's calendar via n8n or GoHighLevel |
book_appointment |
Books a chosen slot and returns a confirmation | Same calendar, plus a CRM update |
lookup_customer |
Finds an existing contact by phone or name | CRM search |
create_lead |
Saves caller details and the reason for the call | CRM or a sheet |
check_service_area |
Confirms a zip code is covered | A simple list the client maintains |
send_sms |
Texts the caller a link or confirmation | Twilio through n8n |
Booking is the one every client wants, and I wrote a full walkthrough in voice AI appointment booking. The n8n side of the wiring is in how to connect Retell AI to n8n.
How to design a function the model uses correctly
Write descriptions like instructions, not labels
The model decides when to call a function largely from its description. "Checks calendar" is a label. "Use this after the caller has said which day they prefer. Returns up to three open slots. Do not call it before you know the service type" is an instruction. The second version prevents the agent from calling the calendar before it knows what it is booking.
I also mirror the description in the main prompt: a short section that says which function to use at which step. Belt and braces, because the cost of a wrong call is a confused caller.
Keep the parameters few and spoken-friendly
Every required parameter is a question the agent has to ask. Ask for the minimum. If the backend needs a calendar ID, a location ID or an API key, those should never be parameters the model fills. Hardcode them in the endpoint or pass them as dynamic variables, so the model only collects things a caller can actually say: a date, a name, a zip code.
Use enums wherever you can. If the service type must be one of "cleaning", "checkup" or "emergency", say so in the schema. Free text invites the model to invent a value your backend does not recognize.
One job per function
A single handle_booking function that checks availability, books, reschedules and cancels depending on a mode argument is easy to write and hard for the model to use. Split it. Small, single-purpose functions with clear names get called correctly far more often, and they are easier to debug when a client reports a problem.
Return results the agent can say out loud
Whatever your endpoint returns, the agent reads it. Do not return a raw JSON dump of 40 calendar slots with ISO timestamps. Return something like "Open slots: Tuesday at 10 am, Tuesday at 2 pm, Wednesday at 9 am." Do the formatting in n8n, not in the prompt. The model should never be converting time zones or parsing timestamps while a caller waits.
Speed: the part that decides whether it feels human
A function call is dead air unless you handle it. Retell lets the agent say something while the function runs, like "Let me check the calendar for you", and that small line covers a surprising amount of delay. Turn it on for anything that takes more than a moment.
Then make the backend fast. My rules:
- One lookup per function. Not a chain of five API calls.
- Cache what does not change. Service lists, hours and zip code coverage do not need a live fetch on every call.
- Set a timeout and return a fallback. If the calendar API hangs, return "I could not reach the calendar" within a few seconds rather than letting the caller sit in silence.
- Warm your workflows. A cold serverless function or a sleeping webhook host adds seconds to the first call of the day.
More on the latency side in how to reduce voice AI latency.
Failure handling: plan for the bad call
Functions fail. Calendars go down, CRMs rate limit, a caller gives a date that does not exist. What matters is what the agent does next. I always return a clear, speakable error and write prompt rules for it:
- Lookup found nothing: treat the caller as new, do not say "error"
- Booking failed: apologize once, collect the caller's preferred time and number, create a lead, and tell them the office will confirm
- Backend unreachable: offer a transfer during business hours, a callback otherwise
The goal is that no function failure ever ends the call without a next step. The worst outcome is an agent that confidently says "You're booked!" when nothing was booked. That is a hallucination in the most expensive place possible, and the guardrails for it are in voice AI agent hallucinations. My rule: the agent only confirms a booking if the function returned a confirmation, and the prompt says so explicitly.
Security: your endpoint is on the public internet
The URL you give Retell is reachable by anyone who finds it. Treat it like any other API:
- Verify requests come from Retell. Retell signs its requests, so check the signature in your endpoint and reject anything that does not match.
- Never trust the arguments blindly. The model fills them from what a caller said. Validate types and ranges, and never let a caller-supplied value pick which client's data you touch. Resolve the client from the agent or the dialed number, not from the conversation.
- Return only what the call needs. A customer lookup should return a first name and a status, not the full CRM record. Whatever you return can end up in the transcript.
That last point matters for healthcare and legal builds in particular. See HIPAA compliant AI receptionist.
Testing functions before go-live
I test every function three ways:
- Directly, by calling the endpoint with sample arguments, including bad ones
- Through the agent, with scripted test calls that should and should not trigger it
- Under failure, by breaking the backend on purpose and confirming the agent recovers
Then I read the transcripts and the function call logs together. You want to see the agent calling the right function at the right step, with sensible arguments, and handling the result correctly. My full pre-launch process is in how to test a voice AI agent. After launch, post-call analysis is how I catch calls where a booking was attempted but not confirmed.
Single prompt or conversation flow?
Functions work in both Retell agent types. In a single prompt agent the model decides when to call them based on descriptions and prompt rules. In a conversation flow agent you can attach functions to specific nodes, which makes the order much more predictable: availability is always checked before booking because the flow says so. For booking-heavy agents with strict steps, I lean toward conversation flow. The tradeoffs are in Retell AI single prompt vs conversation flow.
Where VoiceDash fits
Custom functions make the agent useful. They do not make that usefulness visible to the client paying you. The client does not see your n8n executions. They see their calendar filling up and wonder whether the agent did that or their front desk did.
That is the gap we built VoiceDash for. It connects to your Retell account and pulls calls, recordings, transcripts and usage into a branded portal with your logo, on your domain, with each client scoped to only their own data. A client can open any call and hear the agent check availability and book the slot. Live in under 10 minutes, no code. Plans are Starter, Growth and Ultimate from $19/mo with a 7-day free trial. VAPI and Bland support are coming soon. More on what to show clients in voice AI client reporting.
Custom functions checklist
- Check whether a built-in function already does the job
- Descriptions written as instructions, mirrored in the prompt
- Minimum parameters, enums where possible, no IDs or keys for the model to fill
- One job per function
- Results formatted for speech in the backend
- A spoken line while the function runs
- One fast lookup, caching, and a timeout with a fallback
- A speakable error and a prompt rule for every failure mode
- Request signatures verified, arguments validated, minimal data returned
- Tested directly, through the agent, and under failure
The bottom line
Custom functions are where a Retell agent starts earning its retainer. Keep each function small and single-purpose, make the backend fast and the results speakable, assume every call can fail and script the recovery, and lock down the endpoint like the public API it is. Do that and the agent books real work instead of just sounding good on a demo.
Want each of your clients to see every booking call, recording and transcript on your domain? Start free on VoiceDash or book a demo and I will show you how agencies set it up.