Skip to main content
Flows are dynamic: a screen can greet the user by name, show a premium-only price, or branch on whether the user has onboarded. That data comes from two places: SDK context you pass in, and variables the flow defines in the editor. This page covers how the two connect and how to read or write variables from your app.

SDK context

SDK context is a flat key/value map you provide at configure time. It is the bridge between your app’s state and a flow’s variables, and it also feeds audience targeting.
FlowPilot.configure({
  apiKey: 'fp_live_...',
  appId: 'your-app-id',
  context: {
    'user.id': 'user_123',
    'user.name': 'Jordan',
    'user.is_premium': false,
    'user.plan': 'free',
  },
});
Keys are plain strings, conventionally dot-namespaced (user.is_premium) to match how variables reference them. Values can be strings, numbers, booleans, or arrays.

How context reaches a variable

In the editor, a variable can be sourced from SDK context. Such a variable carries an SDK path; when a session initializes, the store reads the context entry whose key equals that path. If the context has no matching key, the variable falls back to its constant source, then its default value, then its type’s zero value ('', 0, false, or []). So a variable sourced from user.is_premium reads context['user.is_premium']. The key in your context must match the variable’s SDK path exactly.
There is no public updateContext method on FlowPilot in this build, and no per-present context argument. Context is read at configure time and when each session is created. To change identity or attributes (for example after login), call FlowPilot.configure(...) again with the new context before presenting the next flow. See Configuration.

Variable value types

A flow variable has one of four types. At runtime, values are one of these TypeScript types:
type VariableTypeName = 'string' | 'number' | 'boolean' | 'list';

type VariableValue =
  | string
  | number
  | boolean
  | string[]
  | number[]
  | boolean[];
A list variable also declares its item type (string, number, or boolean) in the editor.

Reading and writing variables at runtime

On the declarative path you hold a FlowSession, whose variableStore is public. Use it to read or write variables from host code (for example to seed a value before start(), or to read the user’s choices after completion).
const session = await FlowPilot.createSession('paywall_main');

// Read
const isPremium = session.variableStore.get('user.is_premium'); // VariableValue | undefined
const all = session.variableStore.getAll();                     // Record<string, VariableValue>

// Write (returns false if the key is unknown or the variable is read-only)
const ok = session.variableStore.set('selected_plan', 'annual');

session.start();
Key methods on variableStore:
MethodReturnsNotes
get(key)VariableValue | undefinedLooks up by variable key.
getByLabelOrKey(labelOrKey)VariableValue | undefinedTries the key, then the human label.
getAll()Record<string, VariableValue>Snapshot of every variable.
set(key, value)booleanfalse if the key is unknown or the variable is not writable.
contains(key)booleanWhether the variable exists.
interpolate(template)stringSubstitutes {{var}} placeholders in a string.
set(...) respects the variable’s writable flag set in the editor. A read-only variable (for example one sourced directly from SDK context) returns false and is not changed, with a warning logged. Make the variable writable in the editor if your app needs to mutate it.

Using variables inside a flow

Most variable use happens inside the flow itself, authored in the editor: a text component shows Hi {{user.name}}, a price switches on user.is_premium, a condition node branches the navigation. Your app’s job is just to supply the context; the editor decides how variables drive the UI. {{ }} placeholders do plain string substitution. To switch a value (not just substitute one) based on a condition, the editor uses a conditional property value, not inline logic.
{{ }} interpolation does string substitution only. There is no ternary or conditional syntax inside {{ }}. To switch a value based on a condition, use a conditional property value (case/else against a condition) instead.
See Variables and Dynamic values for how flow builders author these.

Identity and the per-install user ID

The SDK generates a stable per-install user ID and persists it with expo-secure-store, so it survives app restarts. This ID buckets the user into A/B experiments deterministically (the same user always gets the same variant).
There is no public API to set a custom user ID in this build. If a user appears to switch experiment variants between launches, their stored ID was reset (a reinstall, cleared secure store, or a different device), not a bug in bucketing.
TODO: document a setUserId API here if one becomes public; SessionManager.setUserId exists internally but is not exposed on FlowPilot. Verify against flowpilot-EXPO-SDK/src/FlowPilot.ts.

Common mistakes

  • Context key does not match the variable’s SDK path. The variable reads context[path]. A mismatch means the variable silently falls back to its default. Match the keys exactly.
  • Trying to mutate a read-only variable. set(...) returns false for a non-writable variable. Mark it writable in the editor.
  • Expecting updateContext. It is not exposed. Re-configure to change context for future sessions.
  • Putting logic inside {{ }}. Interpolation is substitution only. Use a conditional property value in the editor to switch values.

Troubleshooting

  • A {{user.name}} placeholder renders empty. No context entry matched the variable’s SDK path, and it had no default. Confirm the context key equals the variable’s path, set at configure time.
  • set(...) returns false. Either the variable key does not exist in this flow, or it is read-only. Check the editor’s variable definition. Enable logLevel: 'debug' to see the warning.
  • A user keeps flipping experiment variants. Their per-install ID is being reset between launches. Test on a persistent device/simulator. See Reading experiment results.