{{userdata.name}}, {{vars.api_domain}}
and {{system_vars.date}} are substituted when the agent starts, so one stored
definition addresses the person it actually reached.
A token whose root is not one of ours is an error when the agent is saved, not
text. Talqing does not forward {{customer.number}} to the model and hope.
The six roots
The three refusals are errors at save, with the reason in the message: tool
arguments do not exist outside a tool call,
tooldata exists only while the tool
that wrote it is running, and a workspace secret is a credential for a tool to
send rather than text for the model to read. Everything about the tool side of
templating — tooldata versus userdata, publish_fields, set_variable — is on
templating and data.
One extra token exists and belongs to recording: {{consent.notice}}, legal in a
greeting and nowhere else. See recording.
Tokens that are not ours
Talqing matches anything shaped like a token, not only the roots it knows, so these are all refused when you save:
The error reads, for example:
description, summary_prompt
and message, because all three are substituted before the model or the caller
sees them.
vars
config.vars is what this agent declares it reads as {{vars.name}}. A
declaration is not a value — it is the contract, and the values arrive per session.
string
required
Matches
[A-Za-z_][A-Za-z0-9_]*, and unique within the agent. A name declared
twice is refused: each name gets one description and one default, and the later
entry would silently win.string
default:""
For your teammates and the CoPilot. Never substituted anywhere.
string | null
default:"null"
What
{{vars.name}} resolves to when the session supplied no value. null
means “empty unless supplied”.boolean
default:"false"
Refuse the session rather than resolve this to nothing. A
default satisfies it
outright.POST /v1/calls/token,
POST /v1/calls/outbound, POST /v1/calls/batches and POST /v1/conversations —
and override the declared defaults. vars values are strings only; an integer is
refused, because substitution is textual and a reference number like "007" is
not the integer 7.
There is one bag per session, and it reaches every agent the session runs: the
entry agent, every team member, and a handoff target that was never in the plan.
Each of them merges that bag over its own declared defaults, so a handoff target
falls back to its defaults rather than inheriting the source agent’s. Nothing
inside the session can write vars — no tool, no hook, no model.
Four things to get right
Values are visible to the model. Anything invars is substituted into the
prompt the model reads, so it can be repeated back or read aloud. A credential
belongs in a workspace secret, read as {{secrets.NAME}} from
a tool, where the model never sees it.
required: true refuses the session. A variable that is required, has no
default, and gets no value refuses the call token, the dial, the batch and the
text conversation — before anything is compiled and before any provider is called:
{"api_domain": ""} is a caller deliberately
blanking a default, and it wins over the default like any other string. A default
satisfies required outright. Nothing is enforced once a session is connected — a
handoff target that needs a value nobody supplied reads it as empty rather than
ending the call mid-conversation.
An inbound call or message has no request of ours, so only the declared defaults
resolve. That makes the rule above a hard constraint for inbound voice: a voice
agent that requires a variable with no default cannot answer a phone number at all.
All three doors into “this agent answers this number” refuse it — assigning the
number, publishing that config while the agent is already assigned to one, and
rolling back to a version that predates the default:
agent_override.vars and the top-level vars are different things.
agent_override.vars changes what an agent declares for one call — the
declarations and their defaults. The top-level vars on the same request supplies
the values. Both can appear on one request and they do not conflict: the override
decides what is declared, the top-level bag what it is worth. Because the required
check runs on the merged config, an override that adds a default satisfies it.
See per-call configuration.
Reading a variable nobody declared
{{vars.x}} where x is not in config.vars is a warning, not an error:
system_vars, whose key space is closed — Talqing fills it, so
a name outside the catalog can only be a typo.
system_vars
Six keys, filled in by Talqing. Any other name is refused when you save.GET /v1/catalog returns the list as system_vars.
human_phone_number is the other party either way — the caller on an inbound call,
the person you dialled on an outbound one — so a prompt never has to work out which
end it is on. One agent can greet a caller and someone it called differently by
branching on {{system_vars.direction}}.
The three call keys are empty on web calls and on text conversations. Only a
voice agent is ever dispatched onto a phone call, so writing one into a text or
video agent earns a warning saying it will always be empty. Do not make one the
only source of a fact the agent needs.
The three clock keys work on every channel and are rendered against the agent’s
timezone (an IANA name such as Asia/Kolkata). Using one with no timezone set is
a save error:
{{system_vars.now}} is the machine format — send it to an API, never read it
aloud. Writing it into a greeting earns a warning, because a text-to-speech voice
cannot say an ISO timestamp; use {{system_vars.time}} or {{system_vars.date}} in
a spoken line.
When the clock is read
The prompt is resolved once, when the agent is built: on a call that is the moment
before it answers, on a handoff the moment the target takes over, on text the start
of a cold conversation window. Re-resolving it per turn would rewrite the prompt
prefix and throw away the provider’s prompt cache for the rest of the call. So an
agent that has been talking for forty minutes still reads its own
{{system_vars.time}} as the time it picked up.
A tool resolves per run, so {{system_vars.now}} inside a tool is the time that
tool ran — which is what you want in a created_at you send to a CRM.
Which one do I use?
Use
userdata for facts about the person and vars for configuration of the
session. If a value would be wrong to replay into that person’s next
conversation, it is a var.
Next
Userdata
Session state about the person, and how tools write it.
Templating and data
The tool side:
args, tooldata, publish_fields, set_variable.Secrets
Where credentials go, and how
{{secrets.NAME}} resolves.Per-call configuration
agent_override, inline agents, and what a single call can change.