{{variables}} of your agent have a default value you set in the Builder. On a call you can replace them with that call’s values: the customer’s name, their CRM contact ID, the branch they called. The agent hears them in its prompt, says them in its first message and passes them to its tools.
Where the values come from
When the same name has several values, this order wins: system variables (
system__*, filled by Ryvo), then the call’s value, then the agent’s default. A variable with no value at all stays with its braces, so you can spot it in the transcript.
What they reach
- The prompt, including every stage of a flow.
- The first message and the voicemail message, which the agent says out loud.
- The description of End call.
- Tool parameters whose value comes from a dynamic variable. The name does not have to appear in the prompt: a tool can use
tenant_slugeven if the prompt never mentions it.
{{system__call_id}}: the call’s ID in Ryvo, the same one your webhooks receive, handy to log the call in your CRM from a tool.
Limits and how values are cleaned
- Names: letters, digits and underscore, up to 64 characters, never starting with
system__. InPOST /v1/calls, keys with other names (for exampledeal-id) stay as opaque metadata: they travel in theconversation.startedwebhook but never reach the agent. - Up to 50 variables per call (more is a
400 invalid_bodyin the API), up to 2000 characters per value and 8 KB in total. - Numbers and booleans become text (
"42","true").nullkeeps the default. - Control characters are removed, and
{{or}}inside a value become a single brace, so a value can never create a new variable.
The call initiation webhook
For inbound phone calls. Before answering, Ryvo sends your server who is calling and uses the variables you return. Meanwhile, the caller hears the phone ringing.1
Create an endpoint
In Settings › Webhooks (or from the Builder), create an endpoint with your server’s HTTPS URL. Its signing secret is the one that signs these requests too.
2
Turn it on in the agent
In the Builder, open Call settings › Call initiation webhook, turn on Ask my server when a call comes in and pick the endpoint.
3
Adjust the wait
Maximum wait time goes from 0.5 to 4 seconds (2 by default). Turn on Let it change the first message if your response may bring the agent’s first message.
4
Publish
Inbound calls use the published version.
The request
APOST with JSON, signed with X-Ryvo-Signature exactly like the events (see Verify signatures), plus X-Ryvo-Event: conversation.initiation and X-Ryvo-Event-Id. The endpoint receives it whatever events it is subscribed to.
caller_id and called_number keep the names ElevenLabs uses. There is no session ID yet; the stable key is call_sid, and the same call_sid can arrive more than once if Twilio retries.
The response
Answer with a2xx and this JSON (the same shape ElevenLabs accepts):
dynamic_variablesfollows the limits above.first_messageis used only if Let it change the first message is on, the agent has no flow and it already speaks first. Up to 1000 characters, and it can use variables too.- Any other override (prompt, language, voice) is ignored.
- A body over 8 KB, invalid JSON or a different
typecounts as a failure.
When it fails
If your server does not answer in time, answers something other than2xx, or the response is invalid, the call is answered anyway with the default values. The result (ok, timeout, error or invalid, with the HTTP status and the latency, never the body) is stored with the call. You can turn the webhook off at any time from the same section.