Variables and extraction

Variables carry data through a conversation. They arrive in two ways: you pass them in, or the agent captures them from what the caller says.

Passing variables in

Variables are seeded when a session starts - a customer's name, an account tier, an order reference - and are available immediately, so the agent can open with them. They can come from:

  • The sessions API - variables when you open a session with POST /workflows/{uuid}/sessions.
  • The calls API - variables on a text call. A phone call placed through the calls API does not carry them.
  • A campaign - every column of a contact's row other than the phone number becomes a variable for that contact's call. See Campaigns.
  • Your server - set dynamic_config_url on the agent and Glytos POSTs {"workflow_uuid": ..., "mode": ...} to it as every session starts, on any channel. A variables object in the JSON reply is merged in; variables passed explicitly win over it. If the request fails or times out (10 seconds) the session starts without them.
  • The Playground, for testing.

The public browser chat and a browser web call have no way to pass variables directly; use dynamic_config_url for those.

Use them in any prompt or message with {{name}}. Nested values are reached with a dot, as in {{customer.tier}}:

Greet {{customer_name}} by name and confirm you are calling about order {{order_id}}.

A variable that is not set renders as nothing, not as the placeholder. Hello {{customer_name}}. becomes Hello . when no name was passed, so write prompts that still read correctly when a variable is missing.

In a workflow, variables can also be used in edge conditions, so the conversation can branch on data you already had before the caller said a word.

Capturing what the caller says

Extraction pulls structured values out of the conversation. It is configured per conversation node (on a prompt agent, on the agent) under extract. Each field has a name and a hint telling the model what to look for:

FieldHint
full_nameThe caller's full name
callback_numberA phone number to call back on
preferred_dayThe day they want the appointment

Extraction runs on each caller turn at that step, over the conversation so far. Captured values become variables, so a later step can use {{full_name}}.

Extraction captures what was said - it does not make the agent ask. The prompt has to actually ask for each field. This is the most common reason a field comes back empty.

Required fields and retries

required is a list of field names inside extract:

{
  "fields": [
    { "name": "full_name", "hint": "The caller's full name" },
    { "name": "callback_number", "hint": "A phone number to call back on" }
  ],
  "required": ["full_name", "callback_number"],
  "retry_message": "Sorry, could you give me your name and a number to call back on?",
  "max_retries": 2
}

After each caller turn, if a required field is still empty, the agent replies with retry_message instead of moving on or answering from the model. It does this up to max_retries times at that step (default 2); after that the conversation continues normally rather than trapping the caller in a loop. Without a retry_message a short generic line is used.

Where captured values end up

Variables are stored on the session, visible in the dashboard, included in the end-of-call report, and delivered on the session.completed webhook - which is how they reach your CRM.

A chat session completes, and session.completed fires, only when the conversation reaches an end - an end step, a matched end phrase, or the max_turns limit. A chat that is simply abandoned stays open and sends no session.completed.