Skip to main content

Documentation Index

Fetch the complete documentation index at: https://docs.poly.ai/llms.txt

Use this file to discover all available pages before exploring further.

This page requires Python familiarity. Variables are set and read in Python functions.
Variables are defined by setting a property on the conv.state object within a function. You can choose a name for your variable and update its value to anything you want like so:
conv.state.my_variable = 1
conv.state.my_other_variable = {
    "property": "value"
}
These variables will retain their state between turns of the conversation and can be referenced in subsequent tool calls like so:
if conv.state.my_variable == 10:
    return "Well done you hit 10"

Reading variables that haven’t been set

Reading a conv.state variable that was never assigned returns Python None – it does not raise AttributeError or KeyError. Both attribute and dictionary access are supported and equivalent:
conv.state.foo            # None if never set
conv.state["foo"]         # None if never set
conv.state.get("foo")     # None if never set (with optional default)
This enables a few common patterns: Defensive defaults with or – use when any falsy value should be replaced:
attempts = conv.state.verification_attempts or 0
intent = conv.state.call_intent or "other"
Note: or cannot distinguish “never set” from a stored falsy value (0, "", False, None). Explicit unset check with is None – use when the variable is intentionally initialized to None in the start tool as a marker that no value has been collected yet:
def start_function(conv: Conversation):
    conv.state.booking_time = None   # explicit "not yet collected" marker
    conv.state.customer_id = None

# later, in a flow step
if conv.state.booking_time is None:
    return "What time would you like to book?"
Strict “key was assigned at all” check with in – use when you must distinguish “never assigned” from a stored None:
if "booking_time" in conv.state:
    ...
Initializing variables to None (or a sensible default like "" or 0) in start_function is recommended whenever a variable is referenced in a prompt template or read in a flow step before it is guaranteed to be set, so template references and conditional checks always resolve predictably.

Built-in state keys

The conv.state object comes pre-populated with system-managed keys. These are set automatically by the platform and available in every conversation:
KeyTypeDescription
from_strCaller’s phone number (note the trailing underscore – from is a Python reserved word)
tostrCalled number (callee)
call_sidstrUnique call session identifier
asr_lang_codestrActive ASR language code (e.g., "en-US")
tts_lang_codestrActive TTS language code (e.g., "en-US")
shared_idstrShared identifier for correlating conversations across systems
handoffobjectHandoff configuration object (destination, reason, SIP method)
disable_recordingsboolWhether call recording is disabled
stop_recordingboolWhether recording has been stopped mid-call
use_tts_for_responsesboolWhether to use TTS instead of pre-recorded audio
asr_providerstr or dictOverride the default ASR provider
asr_configdictCustom ASR configuration
listen_for_smsboolWhether SMS listening is enabled (default False)
handoff_reason and handoff_number are deprecated. Use the handoff object instead, which supports structured SIP configurations (REFER, INVITE, BYE).
You can read these values in any function:
log.info(f"Caller: {conv.state.from_}, Callee: {conv.state.to}")
log.info(f"ASR language: {conv.state.asr_lang_code}")

Prompt templating

Variables can be used inside tool calls and injected dynamically into prompts shown to the LLM. To inject a variable’s value into your prompt, use the syntax $variable_name. The system will replace this placeholder with the variable’s value wherever it matches. Example: In your start function, you can write:
from datetime import datetime

def start_function(conv: Conversation):
    conv.state.current_date = datetime.now().strftime("%B %d, %Y")
…then in your prompting: The current date is $current_date. …becomes: The current date is September 06, 2024. When using variable templating, ensure the stored value is readable by the LLM. Complex objects like dictionaries or datetime will be stringified automatically.

Environment configuration

You can use the conv.env property to define environment-specific functions and activate test features in sandbox or pre-release environments. For example:
if conv.env == "sandbox":
    # enable early feedback flow
    pass
elif conv.env == "pre-release":
    # activate staging tools
    pass
elif conv.env == "live":
    # run production features
    pass

Dynamic updates

The value templated into the prompt is always kept up to date, so any updates will be reflected in the next turn sent to the LLM. Example:
from datetime import datetime

def set_fake_date(conv: Conversation):
    conv.state.current_date = datetime(1995, 3, 22).date().strftime("%B %d, %Y")
After running this function, the resulting prompt would display: The current date is March 22, 1995. …in the next turn.

Deleting a variable

To delete a variable, remove it from the state within a function:
del conv.state['variable_name']

Variables in the Conversations API

All conv.state variables – both built-in keys and custom variables your agent writes – are returned in the state field of the Conversations API response. This means you can retrieve any state variable programmatically after a call ends. For details on the API response structure, see the Conversations API overview.

conv object

Full reference for conv.state and other conversation properties.

Start tool

Initialize state variables before the greeting plays.

Flows

Use variables to pass data across flow steps.
Last modified on April 30, 2026