Dynamic Variables
One agent, one prompt, different details on every call.
Write {{placeholders}} in the agent's prompt, then send the values with the call. The agent knows which property it is calling about, who it is speaking to, and what the booking says — without you creating an agent per customer.
How it works
Put a placeholder in the prompt in the dashboard:
You are calling on behalf of {{hotel_name}}.
The guest is {{guest_name}} and their stay begins on {{check_in_date}}.Send the values when you start the call:
curl -X POST "https://api.voicetta.com/v1/calls" \
-H "Authorization: Bearer vk_live_your_key_here" \
-H "Content-Type: application/json" \
-d '{
"assistant_id": "c4f2a8e1-9b7d-4e35-a612-7f8c3d5b9e04",
"to": "+14155559999",
"call_variables": {
"hotel_name": "The Pine Ridge Inn",
"guest_name": "Sarah Mitchell",
"check_in_date": "October 14"
}
}'The agent opens the call with those values already in place.
Placeholders work in the greeting too, so the very first sentence can be personalized.
Naming rules
| Rule | Detail |
|---|---|
| Characters | Letters, digits and underscores |
| First character | Must be a letter |
| Length | Up to 64 characters |
| Count | Up to 50 variables per call |
| Value length | Up to 5,000 characters |
So guest_name and booking_ref_2 are fine. guest-name, 2nd_guest and guest name are not.
Values can be strings, numbers or booleans. They all end up as text in the prompt, so "nights": 3 is accepted and becomes 3.
What happens to a name we do not recognize
Nothing, and that is deliberate.
A variable the prompt does not use is ignored. A placeholder with no value is left blank. That is what lets you add a placeholder to a prompt without redeploying the integration that fills it, and add a value ahead of the prompt that will use it.
What is not ignored is a name that breaks the rules. Those are rejected with a 400 naming the key:
{
"detail": [
"call_variables key 'guest-name' must start with a letter and contain only letters, digits and underscores"
]
}A rejection is better than a silent drop here. A mistyped key that we quietly discarded would place a real, billed call with a hole in the prompt and no way for you to notice.
Names you cannot use
Some variables Voicetta fills in itself, and overriding them would break the call rather than personalize it.
| Name | Why | What to use instead |
|---|---|---|
phone_number | The agent's own number | to on the request |
caller_phone_number | The number on the other end | — |
participant_name | Who is being called | customer_name on the request |
system__time | Current time in the workspace timezone | — |
Anything starting system__ or secret__ | Reserved | — |
phone_number is the one that catches people out. In a Voicetta prompt it is the agent's own number, but in a Retell-shaped payload it is the customer's. If we accepted it, an integration ported across would tell the agent it was calling from the number it was calling to. So it is rejected rather than guessed at.
To name the person being called, use customer_name on the request body. It reaches the prompt as {{participant_name}}.
Names you can override
Variables Voicetta fills from your workspace settings can still be overridden per call. hotel_name defaults to your workspace name, and overriding it is exactly what a multi-property integration needs:
{
"call_variables": { "hotel_name": "The Pine Ridge Inn" }
}Which variables does my agent expect?
Ask the API:
curl -H "Authorization: Bearer vk_live_your_key_here" \
"https://api.voicetta.com/v1/assistants"{
"assistants": [
{
"assistant_id": "c4f2a8e1-9b7d-4e35-a612-7f8c3d5b9e04",
"assistant_name": "Front desk",
"call_variables": ["hotel_name", "guest_name", "check_in_date"]
}
]
}This is read from the prompt and greeting themselves, not from a list someone configured, so it cannot drift from what the agent actually says. Variables Voicetta fills in itself are left out, since passing one would be rejected anyway.
They come back
The variables you sent are returned on the call object and on every webhook for that call:
{
"call": {
"call_id": "9f8b1c4e-6d2a-4b7f-8e21-3c5a7d9e0f11",
"call_variables": {
"hotel_name": "The Pine Ridge Inn",
"guest_name": "Sarah Mitchell"
}
}
}Useful when you are reading a transcript months later and want to know what the agent was told at the time.
Variables or metadata?
Both travel with the call, and they do different jobs.
call_variables | metadata | |
|---|---|---|
| Reaches the agent | Yes, substituted into the prompt | No |
| Interpreted by Voicetta | Only as prompt text | Never |
| Shape | Flat, string-like values | Any JSON |
| Size | 50 keys, 5,000 characters each | 8 KB total |
| Use for | What the agent needs to say | What you need to match the call to your records |
Put the guest's name in call_variables. Put your CRM id in metadata.
A worked example
A booking-confirmation call, driven from your own backend:
curl -X POST "https://api.voicetta.com/v1/calls" \
-H "Authorization: Bearer $VOICETTA_KEY" \
-H "Content-Type: application/json" \
-H "Idempotency-Key: booking-48221-confirm" \
-d '{
"assistant_id": "c4f2a8e1-9b7d-4e35-a612-7f8c3d5b9e04",
"to": "+14155559999",
"customer_name": "Sarah Mitchell",
"call_variables": {
"hotel_name": "The Pine Ridge Inn",
"check_in_date": "October 14",
"nights": 3,
"room_type": "Garden Suite"
},
"metadata": {
"booking_id": "48221",
"source": "confirmation-job"
}
}'With this prompt:
You are calling on behalf of {{hotel_name}} to confirm a reservation.
{{participant_name}} has booked a {{room_type}} for {{nights}} nights,
arriving {{check_in_date}}.
Confirm the details and ask whether they need anything before arrival.Note that {{participant_name}} comes from customer_name, not from call_variables.