Dynamic variables
Dynamic variables let you define named placeholders in an agent’s prompt, first message, and webhook tool configurations, then supply concrete values at session start. The same agent definition can serve different customers, tenants, or contexts - just change the values you inject, not the agent.
Defining variables on an agent
Variables are declared on an agent via PATCH /v1/agents/{id}/variables. Each variable has a key, a type, an optional default, and an optional description.
cURL
TypeScript
Python
The PATCH replaces the stored list wholesale. Pass "variables": [] to clear all variables.
Using variables in prompts, first messages, and tools
Reference a variable anywhere in the agent’s prompt, first message, or webhook tool config (URL, headers, body) using double-brace syntax.
Two forms:
{{key}}- plain interpolation. Numbers and booleans are stringified; json-typed values render as their JSON text.{{key|json}}- JSON-encoded form. The value is serialised withjson.Marshal, so a string is quoted and escaped. Use this when injecting inside a JSON body to prevent quote-injection.
Plain interpolation in a prompt:
JSON-safe injection in a tool body - before and after:
Without |json, a string like alice"malicious breaks the surrounding JSON:
With |json:
Using a system variable in a tool URL:
Reserved system__* variables are referenced exactly like customer-scope ones - no special syntax required.
Reserved system variables
The platform auto-populates the following variables at session start. You cannot define or override them - any key beginning with system__ is rejected in the customer catalogue and in per-session overrides.
The GET /v1/agents/{id}/variables response always includes system_variables - the same catalogue above - so your editor UI can surface it without hard-coding the list client-side.
Passing variables at session start
Variables can be supplied at three points. In all cases, per-session values merge on top of agent-level defaults (see Precedence below).
API
Pass dynamic_variables in the body of POST /v1/agents/{id}/conversations (server-to-server) or POST /v1/agents/{id}/sessions (widget/browser flows).
cURL
TypeScript
Python
Widget
Pass variables as a JSON attribute on the <speechify-agent> element. The widget forwards the attribute value to the session-create call automatically.
The dynamic-variables attribute is live today. Any JSON-serialisable object is accepted. Keys in the system__ namespace are still rejected server-side.
SDK
TypeScript
Python
Precedence
When the platform resolves a variable at session start, it applies values in this order - later entries win:
- Agent default - the
defaultvalue stored on the variable definition. - Session override - values supplied in
dynamic_variableson the conversation or session create call. - Reserved
system__*- platform-populated values always win and cannot be shadowed.
Limits
A typo in a template reference never breaks dispatch. The agent will simply receive an empty string for the unresolved token. Use GET /v1/agents/{id}/variables to verify the keys your prompt references are actually defined.
What’s next
Tool-response assignment (an AIS-2680 follow-up) will let variables update mid-call from data returned by a tool, enabling stateful context accumulation across conversation turns.