Guides
Voice agent
An agent is only as good as its system prompt. This page shows you how to write one, gives you three ready-made samples to copy, and covers the limits you need to plan around.
1systemPrompt structure
A good prompt has four parts. Skip any one of them and the agent will eventually get stuck and not know what to do next - it either goes quiet or makes something up.
- Who I am - one or two sentences: company name, role, tone of voice. The agent needs to establish this identity in its very first line.
- What I can do - the concrete tasks the agent actually handles (orders, appointments, information) - not a vague "I can help with anything".
- What I NEVER do - the boundaries: what the agent must never invent, promise or disclose. This part gets skipped most often, and it's exactly what separates an agent that makes up prices from one that fairly says "I don't know, call...".
- How to end the call - when and how to close the call (summary, goodbye) and what to do when the caller wants something out of scope.
Three complete samples - copy them and adapt to your case:
Cafe receptionist
You are the voice receptionist for Nula Cafe in Vinohrady. You speak
calmly, warmly and briefly - the way an experienced staff member would,
not a robot.
WHAT YOU CAN DO:
- Take pickup orders (coffee, tea, croissants, sandwiches).
- Tell callers the current opening hours: Monday to Friday 8am-6pm,
weekends 9am-3pm.
- At the end of an order, repeat it back in full and confirm the pickup
time (at least 15 minutes from now).
WHAT YOU NEVER DO:
- Never make up prices or items that aren't on the menu - say that
staff will confirm the exact price on site.
- Never promise delivery, the cafe doesn't deliver.
- Never pretend to be human when a caller asks you directly - say
you're the cafe's voice assistant.
HOW TO END THE CALL:
Summarize the order and pickup time, wish them a good day, and end the
call. If the caller wants something you can't handle (complaints,
catering), tell them to call again during business hours and speak to
the owner directly.Satisfaction survey
You're calling on behalf of Botanika, an online store, for a short
satisfaction survey after a recent order. You're polite, get straight
to the point, and don't drag the call out.
WHAT YOU CAN DO:
- Ask if the customer has a minute for three quick questions.
- Question 1: how would they rate their satisfaction with the order,
on a scale of 1-5.
- Question 2: did the package arrive on time?
- Question 3: is there anything we could improve?
- Remember the answers and summarize them briefly at the end of the
call.
WHAT YOU NEVER DO:
- Never push a customer who declines or says they have no time - end
the call politely right away.
- Never handle complaints or returns - that belongs on the customer
support line, which you can read out on request.
- Never offer discounts or coupons, you don't have that authority.
HOW TO END THE CALL:
Thank them for their time and feedback, wish them a good day. If the
customer says at any point they don't want to continue, end the call
politely right away with no further questions.Front desk / gatehouse
You are the voice front desk for Nordwex, an office building in
Pankrac. Couriers, visitors and suppliers call this number.
WHAT YOU CAN DO:
- Find out who's calling and why (a courier with a package, a visitor
for a meeting, a supplier).
- For a visitor, get their name and who they're meeting, then tell
them to check in at the ground-floor reception and wait until
someone comes for them.
- For a courier, tell them to leave the package at reception and write
the company name and recipient on it.
- Take a short message when the person they're calling for isn't
available right now.
WHAT YOU NEVER DO:
- Never give out employees' private mobile numbers - offer to
transfer to reception or take a message.
- Never let anyone go "up alone" - all visitors go through reception.
- Never share who is currently in the building or when - say they
need to check with reception.
HOW TO END THE CALL:
Repeat back what was agreed (message, waiting at reception, transfer),
wish them a good day, and end the call.2firstMessage
firstMessage is the first sentence the customer hears - right after they pick up for an inbound call, or right after the callee answers for an outbound one.
- Short, spoken English - the way a person would say it, not the way they'd write an email.
- Say right away who or what is calling/answering - the customer needs to know who they're talking to within three seconds.
- End with an open question ("how can I help", "got a minute") - not a long monologue.
- Read it out loud - text that looks fine written down can sound clumsy spoken.
- For outbound calls, introduce yourself and the reason for calling right at the start - people are wary of picking up unknown numbers.
3Tools
A tool is the address of your API, which the agent calls in the middle of a call and uses the response right away in speech. Without a tool the agent can only talk; with one it can verify an order, find an open slot, or log a booking.
Tools are created in the portal at /en/agent/tools (or via POST /v1/tools), then turned on for an agent with a checkbox on its detail page (the toolIds field in the API). A tool belongs to the account, not to an agent - the same tool can be used by multiple agents. You specify four things for it:
- Name - a readable one ("Verify order"). The name the model sees is derived from it automatically (
overit_objednavku) and shown under the field. - When the agent should use it - the only thing the model bases its decision to call the tool on at all. Write it as an instruction: "Use when the caller asks where their order is."
- Address and method -
httpsonly, publicly reachable.GETsends parameters in the query string,POSTin the JSON body. Plus headers, typicallyAuthorization. - Parameters - for each one you say where its value comes from: the model pulls it from the call, the caller's or called number is filled in automatically, or it's a fixed value.
This is what the request that arrives at your endpoint during the call looks like:
POST https://api.yourapp.com/orders
Content-Type: application/json
Authorization: Bearer your_key
{
"order_number": "A-42",
"phone": "+420777123456"
}And this is the response the agent can work with - a short JSON payload it can turn into a single sentence:
{
"status": "shipped",
"delivery": "tomorrow morning"
}Try the tool before you save it
The form has a Try it button: it sends a real request to the given address with sample values and shows the status, response time, and the start of the response. Nothing is saved in the process. It's worth doing - an endpoint that responds slowly is heard by the caller as silence during the call.
Limits: at most 10 tools per account, 10 parameters and 5 headers per tool, a response timeout of 5 to 30 seconds (20 by default). We only ever show header values back to you masked (Bear***) - the full value can't be read back from the account.
4Handoff to a human
The agent can hand the call off to your number when the caller asks for a person or runs into something the agent can't resolve. It's turned on in the agent's detail page (the transferTo field in the API); you write the condition as an instruction to the model in transferCondition. Without one, we use a default sentence.
Two things worth knowing up front
We don't pass a call summary to the human. The caller hears that they're being transferred, but the person on the other end picks up the caller directly - there's no "warm transfer" where the agent briefs the human first; the phone network doesn't support that. Plan for it in your instructions: have the agent tell the caller they may need to repeat themselves.
A handoff is a regular outbound call, and it's billed as one: 0.92 CZK/min no agent surcharge (the agent is no longer on this leg). You can spot it in the call history by its transfer kind. The inbound leg keeps running and is billed separately.
You can't transfer to your own volai number - the call would loop back on itself until the credit ran out. Premium-rate lines (90x) are banned for the same reason.
5Data captured from calls
Instead of reading the full transcript, you can specify exactly what you want out of a call - a name, an item count, whether it's urgent. The agent fills it in after the call, and you get it back as JSON.
Each field has a key, a type, and a description. Up to ten fields per agent:
- Key (
key) - lowercase letters, digits and underscores, up to 40 characters. You'll find the value under this name in the result. - Type (
type) -string,number, orboolean. - Description (
description) - exactly what the model should pull out, 5 to 500 characters. Also say what it should do when the call doesn't mention it. - Options (
enumValues) - an optional list, for text fields only. The model then only picks from the offered values, so the result can be filtered directly.
curl -X PATCH https://volai.cz/v1/agents/ag_kx91fa2b \
-H "Authorization: Bearer vk_YOUR_KEY" \
-H "Content-Type: application/json" \
-d '{
"dataFields": [
{"key": "name", "type": "string", "description": "The caller's name, as they stated it. Leave empty if not mentioned."},
{"key": "coffee_count", "type": "number", "description": "How many coffees the caller ordered."},
{"key": "urgency", "type": "string", "description": "How urgent the request was.", "enumValues": ["low", "normal", "high"]}
]
}'The result shows up in three places: on the call's detail page in the portal as a "Captured data" card, in the data field on the call (both GET /v1/calls and GET /v1/calls/{id}), and in the call.completed webhook body.
{
"call": {
"id": "c_8f2ac1d4",
"status": "completed",
"hasRecording": true,
"data": {
"name": "Jane Smith",
"coffee_count": 2,
"urgency": "normal"
}
}
}A null value means "not mentioned in the call" - the same applies if the model returns an empty string. If an agent has no fields configured, the data key isn't in the response at all.
6Recordings
Agent calls are recorded, and you can play them straight from the call's detail page in the portal - clicking in the transcript jumps to the matching point in the recording. To download or play it elsewhere, use GET /v1/calls/{id}/recording (MP3, same API key). The hasRecording field tells you whether a call has one.
- We keep them for 90 days after the call, then delete them. The transcript and summary are kept separately and aren't deleted along with the recording. After ninety days, the endpoint returns
recording_expired. - You can turn it off per agent with a toggle on its detail page, or the
recordCalls: falsefield in the API. From that point on, no recording is made. - Only calls handled by the built-in agent are recorded. A direct bridge between two numbers, a relay call, and a SIP call are never recorded.
Informing the caller is your responsibility
Recording a call is processing personal data. The caller needs to know about it - the simplest approach is to say so in the agent's first sentence ("this call is recorded for quality purposes"). volai doesn't say it for you, and it can't judge whether it applies to your case.
7Limits
- A call lasts at most 10 minutes (600 seconds), then the agent ends it itself.
- If the caller stays silent for 20 seconds, the agent treats it as the end of the call and hangs up.
- Languages: Czech (default), plus English, Slovak, German and Polish.
- The agent responds roughly 1 second after you finish speaking - in real traffic this varies slightly with load.
8Voices
voiceId on create_agent/update_agent (and the same-named field in POST/PATCH /v1/agents) picks the agent's voice. GET /v1/voices (MCP list_voices) returns the valid values - the catalog currently holds a single entry:
| id | Description |
|---|---|
| anet | Anet - a young female voice, professional delivery. The voice the template uses today, and every new agent inherits it - skip voiceId and you get exactly this voice, no need to send it. |
The catalog will grow over time - voiceId also accepts a raw ElevenLabs ID for backward compatibility with agents created before the catalog existed. An unknown slug returns an error listing the valid values.
9Pricing
The voice agent is billed on top of the call price, by the second - no rounding up to whole minutes. Rates exclude VAT, like the whole price list.
| Direction | Call | Agent | Total |
|---|---|---|---|
| Outbound | 0.92 CZK/min (~EUR 0.04) | 2.50 CZK/min (~EUR 0.10) | 3.42 CZK/min (~EUR 0.14) |
| Inbound | 0.50 CZK/min (~EUR 0.02) | 2.50 CZK/min (~EUR 0.10) | 3.00 CZK/min (~EUR 0.13) |
Full pricing, with examples, is on the Pricing page.
Prefer your own ElevenLabs, Vapi, or another platform? You can skip the agent surcharge with your own agent - see Bring your own agent.
10Transcripts and webhook
Once a call ends, fetch the transcript and summary via GET /v1/calls/{id} (fields transcript and summary) - or volai can push them to your URL as an event call.completed, once it's ready. The transcript format, signature verification and error handling are on the Webhooks page.
Don't want to wait for a webhook or poll the API? In the portal, every agent's detail page also shows a list of recent calls with the transcript right there to read.
Related
MCP server
Connect Claude Code, Cursor and other AI editors.
REST API
Complete reference for every endpoint, incl. agent tools and recordings.
Webhooks
Events, structured data in the body, signature verification, retries on failure.
Bring your own agent
Connect a third-party platform (ElevenLabs, Asterisk...) - no agent surcharge.