Graine AI

Using your data

Fill each call's own details into what the agent says and decides. Variables and their defaults, the values a call keeps up to date by itself, values picked up during the call, and exactly how a rule compares them.

Every call carries data: the details you send with it, plus values the call works out or picks up as it goes. A flow uses that data in two ways. Text can say it, by writing a variable such as {first_name}. Rules can test it, to choose a path without asking a model.

Variables in text

Write {name} and each call fills it in from its own data. It works in:

  • the welcome message and the briefing;
  • a step's instructions, sample replies and fixed lines;
  • the conditions and tool descriptions of paths the AI decides;
  • the decision guidance;
  • the title of a step that has no instructions (a fixed line or a branch), because that title is what the decision model reads as the step's goal.

The values come from the call: a campaign's columns, the variables of a call placed with POST /v2/calls, or what your app sets for a conversation in it (see Variables in your app).

When a variable has no value and no default, it is left out of the text, so the caller never hears braces. Two places differ:

  • The decision guidance shows the decision model NULL in its place.
  • The welcome message on a phone call is prepared before the call connects. A variable in it with neither a value nor a default is used exactly as written, braces and all.

Give every variable in the welcome message and the guidance a default.

The Variables panel

Variables, in the canvas toolbar, lists every variable the flow uses. The number on the button counts the ones a call can send. The panel has three groups.

From the call's data. Each variable a call can send, where it is used, a box for its default, and its type.

  • A call always uses its own value first. The default is used only when the call doesn't send one, which keeps test calls, and inbound calls that carry none of your data, sounding natural.
  • The type sets how rules compare the value: Detect, Text, Number or Yes / no. See How a rule compares values. A Yes / no variable's default is chosen from No default, Yes and No; a Number variable's default should be a number, and the panel says so when it isn't.
  • A field a rule reads that no path collects, such as one an event brings, is listed here too, with a default of its own.

Filled in during the call. Values the call sets by itself, and fields that paths collect. They take no default. The times and dates are among them: they are worked out from the contact's time zone, so they need one (below).

The contact's time zone is listed with the variables a call sends, because a call has one only if it sends one. Its default is the same zone as Settings › On the call › Time zone, and changing either changes both.

Defaults nothing uses. Defaults left over after you changed the text, each with a button to remove it.

Values the call keeps up to date

Rules can read these by the names below. The date and time values can also be said in text, without the recipient_data. part: {current_date}, {current_time}, {current_weekday} and so on.

FieldWhat it holds
recipient_data.current_hourThe hour where the contact is, 0 to 23.
recipient_data.current_minuteThe minute, 0 to 59.
recipient_data.current_weekdayThe day of the week in lower-case English, monday to sunday.
recipient_data.current_dayThe day of the month, 1 to 31.
recipient_data.current_monthThe month, 1 to 12.
recipient_data.current_yearThe year.
recipient_data.current_dateThe date as text, for example Friday, October 09, 2026. For saying, not for comparing.
recipient_data.current_timeThe time as text, for example 02:30:00 PM. For saying, not for comparing.
recipient_data.timezoneThe time zone the values above are read in: the call's own, else the flow's Time zone.
detected_languageThe language the call is in now, as a code such as hi.
_step_turnsHow many times the caller has spoken on the current step. Silence repeats count. It starts again at 0 whenever the call moves.
_total_turnsHow many times the caller has spoken on the whole call.
_silence_repeatsHow many times the current step has repeated after silence. It starts again at 0 whenever the call moves.
_last_eventThe name of the last event the call received.

The time zone

The date and time fields exist only when the call has a time zone, such as Asia/Kolkata. A call takes it from one of two places:

  1. Its own data. Send it as a variable named timezone with the call: a column of your campaign's list, or in the variables of POST /v2/calls. A call's own time zone always wins.
  2. The flow's time zone. In Settings › On the call, pick a Time zone. Search by city or by offset (Kolkata, +5:30). Every call that sends no time zone uses this one. Choose No time zone to clear it.

The flow's time zone is stored as its default for recipient_data.timezone, so through the API it is defaults.recipient_data.timezone (see the Flow API). A new flow agent has none.

No time zone, no time values

With neither, a rule on a date or time field never holds, and the fields are left out of text. Rules read them fresh on every turn; text is given the values from the start of the call.

Values picked up during the call

Three things add to a call's data while it runs. Each lands under its own name, outside recipient_data, so a rule names it directly (demo_time, not recipient_data.demo_time) and text says it as {demo_time}.

  • Collected fields, filled in by the decision model when it takes a path that collects them (see Collecting values on the way).
  • Event data: the data your server sends with an event (see Events).
  • Tool answers: when one of the agent's tools answers with a JSON object, each of its top-level fields. A tool that answers {"slots_left": 3} lets the next rule test slots_left.

When one of these has the same name as a variable the call was sent, text uses the newer value. Rules can still tell them apart: recipient_data.plan is what the call was sent, plan is what was picked up.

Name them plainly

Picked-up values sit beside the call's own variables, not inside them. Avoid the names the call already uses: a field called recipient_data in event data or a tool answer would replace every variable the call was sent.

After the call, the latest value of every collected field reaches your webhook in collected_fields (see Webhook payloads).

How a rule compares values

A rule's field is a path into the call's data, with dots between the parts: recipient_data.plan, demo_time, _step_turns.

When the field is missing, the rule doesn't hold, whatever its comparison, except is empty. Is filled in holds whenever the field is there, even when it is empty.

When the field has a type, set in Variables or as field_types through the API, both sides are converted to it before comparing, lists included. A value that can't be converted doesn't match.

TypeCompares
NumberAs numbers: a value sent as "18" equals 18.
Yes / noAs yes or no: true, yes and 1 are yes; false, no and 0 are no, in any case.
TextAs text, exactly.

When it has no type (Detect), the comparisons that take one value convert when they can: values of the same kind are compared as they are, text that reads as a number is compared with a number as a number, and a yes / no rule value matches text such as yes or false. Is one of, is none of and contains compare values exactly as given.

That last point is the one to watch. The value box stores anything that looks like a number as a number, so a pin_code sent as the text "110001" is not one of 110001, 110002 until pin_code has a type, Text or Number, which makes both sides match.

Set a type when:

  • a list rule (is one of, is none of) compares values that may arrive as text;
  • a yes / no value arrives as text from a list, an event or a tool;
  • you want a mistyped value to fail rather than be guessed at.

Through the API, types and defaults are part of the flow:

{
  "field_types": {
    "recipient_data.pin_code": "string",
    "recipient_data.seats": "number",
    "recipient_data.auto_renew": "boolean"
  },
  "defaults": {
    "recipient_data": { "company_name": "Northwind", "auto_renew": false }
  }
}

A type is keyed by the field exactly as rules write it. A variable's default goes under recipient_data. See the Flow API.

Next: Tools, transfers and knowledge.

On this page