← Documentation RU

JSON configuration format

A reference for flow.json — the file the visual editor generates

flow.json describes the whole bot scenario: nodes, the edges between them and the project settings. The editor validates the file against a JSON Schema (schemaVersion: "1.0"), so any exported config is guaranteed to load back. Manual edits are safe too: load the file via "Import JSON" and the editor checks it with the same schema.

Tip: the complete specification with generated code examples is in the GitHub repository.

Document structure

{
    "schemaVersion": "1.0",
    "name": "my-bot",
    "version": "1.0.0",
    "platforms": ["telegram", "alisa"],
    "database": { "type": "file", "config": {} },
    "nodes": [],
    "edges": [],
    "fallback": { "text": "Sorry, I didn't understand." },
    "welcome": { "text": "Hello!" }
}
Field Description
schemaVersion Format version, currently always "1.0"
name Project name — used in package.json and the folder name
version Project version (semver)
platforms Platform list: telegram, alisa, marusia, vk, max_app, viber, smart_app
database Data storage: file, mongo or none
nodes All scenario blocks (see the types below)
edges Connections between blocks
welcome Welcome message shown when the dialog starts
fallback Reply to unrecognized input
variables Variable comments: name → description

Node types

Type Purpose
command Command — reacts to trigger words
step Step — waits for the user's reply and saves it to a variable
condition Condition — branches on a variable
action Action — HTTP requests, variables, random numbers
response Response — shows text and buttons without asking for input
end End — closes the dialog

Command

{
    "type": "command",
    "id": "node_123",
    "name": "greeting",
    "slots": ["hello", "hi"],
    "isPattern": false,
    "saveTo": "lastGreeting",
    "response": { "text": "Hi, {{userName}}!", "buttons": [] }
}
Field Description
slots Trigger words, case-insensitive
isPattern When true, slots are treated as regular expressions
saveTo Save the user's input to a variable
response Reply text, TTS, buttons, card, dialog end

Step

{
    "type": "step",
    "id": "node_456",
    "name": "ask_name",
    "prompt": { "text": "Nice to meet you, {{userName}}!" },
    "saveTo": "userName",
    "saveAs": "original"
}

A step runs on the user's reply: the question is asked by the block before the step, and the optional prompt.text is sent after the reply.

saveAs: "original" keeps the input as typed, "lowercase" lowercases it. Where to go next is defined by the next edge.

Condition

{
    "type": "condition",
    "id": "node_789",
    "name": "check_age",
    "variable": "age",
    "operator": "gte",
    "value": 18
}

The yes/no branches are defined by branch_true and branch_false edges. The value may be a number, a string or a variable name.

Comparison operators

Code Check
eq / neq Equals / not equals
gt / gte / lt / lte Greater / greater-or-equal / less / less-or-equal
contains String contains a substring
isEmpty / isNotEmpty Variable is empty / not empty
isSayTrue / isSayFalse User answered "yes" / "no" (natural language)
isUrl Value is a valid URL

Action

Three action types: set_variable (evaluate an expression and write it to a variable), random_number (a random number between min and max) and http_request (a GET/POST request with headers, body and saving the response to a variable). The {{variable}} substitution works in URLs, bodies and expressions.

Edges

{ "from": "node_123", "to": "node_456", "type": "next" }
Type Description
next Sequential transition to the next block
branch_true The "yes" branch from a condition
branch_false The "no" branch from a condition
slot_match Transition on a slot match

Variable substitution

Use {{name}} in any text — the value is substituted automatically:

"Hello, {{userName}}!"  →  setText(ctrl, `Hello, ${ctrl.userData.userName}!`)

Validation and names

Block names with spaces and special characters are automatically turned into valid identifiers. The editor catches typical errors before export: empty replies, unreachable blocks, duplicate names after sanitization, missing connections. Conditions inside one block are isolated — two conditions on the same variable in one block don't conflict.

More