AltScore
Builder Rules

Variables

Variables store and manage data throughout your conversational flow. They capture what the customer answers, hold intermediate values, and pass data between nodes.

Two things to keep in mind before anything else:

  • The type you declare in the variables panel is the one the engine keeps. A node that writes a value of another type does not change the declaration; it leaves a notice.
  • Values live in the conversation, never in the flow. Running a flow never adds, removes or retypes a declared variable.

Variable Types

The builder supports seven variable types, each designed for specific data needs:

String

Text values of any length. Use for names, addresses, free-form responses, and any textual data.

Examples: Customer name, email content, custom messages

Number

Numeric values including integers and decimals. Use for amounts, quantities, scores, and calculations.

Examples: Loan amount, age, score

Date

Date and time values. Use for scheduling, deadlines, and temporal data.

Examples: Birth date, appointment date, deadline

Boolean

True/false values. Use for flags, toggles, and binary states.

Examples: Is verified, has accepted terms, is eligible

Object

Structured data with key-value pairs. Use for storing related data together.

Examples: Profile data, an API response, the result of Extract Information with One result per file off

Array

Ordered lists of values. Use for collections, multiple selections, and lists.

Examples: Selected options, the list of files from Ask File with Multiple files on, one extraction result per file

Attachment

A single file: the value is the signed URL of the file, stored as text.

Examples: ID document, profile photo, signed contract

Attachment or array: one file or a list

Nodes that produce files write one of two shapes, and the toggle in the node panel decides which:

NodeToggleOff writesOn writes
Ask FileMultiple filesattachment - one signed URLarray - a list of signed URLs
Extract InformationOne result per fileobject - one resultarray - one result per file

Attachments that arrive by email follow the type of the variable you chose to store them in: an array keeps every file; an attachment keeps the first one and leaves a warning notice saying how many were left out.

The variable picker in those panels only offers variables of the matching type, and flipping the toggle clears the selected variable because its type changed. Choose the variable after you have settled the toggle.

Nodes that read a file (OCR Verification, Face Verification, Borrower Update, File, Send Email, Document Verifications, Create Asset, Packages) resolve by the shape of the value, not by the declared type:

  • A node that expects one file and receives a list takes the first one and leaves a warning notice naming the variable and how many files arrived.
  • Nodes that accept several files (Document Verifications, Send Email) process one per entry.
  • An empty variable leaves a warning notice and the node exits through its failure path, or continues without the file when the rest of its work is legitimate (Borrower Update, Create Asset).
  • A signed URL that expired is renewed before the node uses it.

The publish gate reports a one-file consumer wired to a variable that holds a list, so you see it before customers do.

How the Engine Stores a Value

The declared type wins

When a node saves a variable, the engine resolves its type in this order:

  1. The type declared in the variables panel of the flow version the conversation is running.
  2. The explicit type the node passes (for example, the toggle-driven type of Ask File).
  3. The type the variable already had in the conversation.
  4. What the value looks like.

The engine only infers a type when nothing declares the variable. Text that parses as the declared type fits: a customer typing 42 into a number variable is a number, true/false (and their common spellings) fit a boolean, and JSON text fits an array or object.

When the value does not fit, it is still saved, under the declared type, and the conversation gets one warning notice with code variable_type_mismatch:

La variable 'monto' recibió un valor que no es number

The notice names the variable, the declared type and the type of the value it received, and points at the node that wrote it. Fix either the declaration or the node; the conversation itself keeps going.

Conversations run the published version

A conversation resolves declared types from the flow version it is running - the published one - never from the draft you are editing. Retyping a variable in a draft changes nothing for live conversations until you publish.

The engine writes the conversation, never the flow

Every runtime write lands on the conversation. Nothing a customer does adds, removes or retypes a variable in the flow definition. If a declared variable disappears from the panel, someone edited the flow.

Values are stored as written

Line breaks, tabs and unusual spaces in a value are preserved on every write. What the customer typed is what the variable holds.

Referencing Variables

Reference a variable in any text the customer reads - message bodies, headers, footers, option labels, prompts - with double braces:

Hello {{name}}, your requested amount is {{loan_amount}}.

The placeholder is replaced by the whole value of the variable. In pickers that accept a path, such as conditions and formulas, order.total refers to a field of the object variable order, and the usage analysis counts it as a use of order.

Unresolved variables never reach the customer

A placeholder whose variable has no value stays exactly as written - the customer sees {{loan_amount}} - and the node leaves one warning notice on the conversation listing every unresolved name in that message. No stand-in text such as [VAR NOT FOUND] or [loan_amount] is ever sent.

This applies to every node that shows text to the customer: Message, File, Interactive Options, Send Card Image, every Ask node, Login, Opt-in, OTP, Speech to Text, AI Router and Liveness Verification. A variable declared in the panel that no node has set yet counts as unresolved.

You see these notices in the conversation's notices panel in Chat and grouped by node in the Flow Notices screen.

Variable Scope

All variables have global scope within the conversation:

  • A variable set in any node is readable from every other node.
  • Values persist for the whole conversation, including after a Jump To into another flow. That is why a variable nobody writes in this flow is a warning at publish time and not an error: another flow, or a campaign's metadata, can fill it before the conversation gets here.

Naming Rules

Variable names must follow specific rules:

Format Requirements

  • Must start with a letter (a-z, A-Z) or underscore (_)
  • Can contain letters, numbers (0-9), and underscores
  • Cannot contain spaces or special characters
  • Case-sensitive (userName and username are different variables)

Valid Names

user_name       ✓
firstName       ✓
_tempValue      ✓
loan_amount_1   ✓

Invalid Names

1stName         ❌  (starts with number)
user-name       ❌  (contains hyphen)
user name       ❌  (contains space)
user@email      ❌  (contains special character)

Built-in and Reserved Names

Built-in variables

These names are available in any customer-facing text without declaring them. The engine fills them from the conversation on every message:

NameValue
nameThe customer's profile name, when the channel provides it
phoneThe customer's phone number, when the channel provides it
borrower_idThe identifier of the customer once the conversation has one
nowCurrent date and time
todayCurrent date

Reserved names

The variables panel refuses these names when you try to declare a variable:

NameWhy
phone, name, now, todayBuilt-in, filled by the engine
liveness_idWritten by Liveness Verification
borrower_id, metadataReserved by the conversation

The Variables Panel

The panel lists every declared variable with its type and how the flow uses it.

Usage indicators

  • Set in: nodes where the variable receives a value
  • Used in: nodes where the variable is read
IndicatorMeaningWhat to do
UnusedNo node reads or writes the variableRemove it, or wire it
Not set in any nodeA node reads the variable but no node in this flow writes itAdd the node that sets it, or confirm another flow or a campaign supplies it

The panel header also counts how many variables are used but never assigned.

The same check runs when you publish: the publish gate lists every variable that nodes read but nobody writes, one warning per variable on its first reader. It warns and never blocks, because a Jump To from another flow or a campaign's metadata can legitimately supply the value.

Read-only panel

The panel is read-only in two situations:

  • You do not hold control of the editor (see Collaborative Editing).
  • You are looking at a version other than the current one from the versions sheet. Variable changes always go to the latest version, so a list built from an old version is never sent.

Templates and sub-flows

Applying a template or inserting a sub-flow merges its variables into yours: the ones the template suggests are added, and when a name already exists in your flow your declaration wins, type included, because your nodes were configured against it.

Best Practices

Naming conventions

  • Use descriptive names: user_full_name instead of x or temp
  • Use consistent casing: choose either snake_case or camelCase and stick with it
  • Prefix related variables: user_name, user_email, user_phone

Type selection

  • Declare the type before wiring the nodes; the engine keeps it, so a wrong declaration produces variable_type_mismatch notices on every conversation.
  • Use number for values that need calculations and date for temporal data, not string.
  • Use attachment for one file and array for a list; match the toggle of the node that writes it.
  • Use object for structured data from API responses or Extract Information.

Organization

  • Remove unused variables to keep the panel readable.
  • Set a variable before any message reads it; a declared-but-unset variable leaves the placeholder in the customer's message and a notice on the conversation.