Automations
Methods for managing automations (workflows) programmatically: creating, editing, publishing, stopping, viewing, and deleting. These are the same actions available in the dashboard under "Automations" — useful if you want to create or change automations from your own system instead of using the visual builder.
What is an automation
An automation is a rule of the form "when X happens → do Y". For example: "when a user completes the 'payment' event → send them a thank-you message", or "every day at 10:00 → send a request to an external server".
An automation is structured as a graph (diagram) made of nodes:
Trigger — what starts the automation. Exactly one per automation: by event, by schedule, or manually.
Action — what to do: send a message, make a request to an external server, change a user field, and so on.
Condition — a branch: if the condition is true, execution follows one path; if not, it follows another (or stops).
Wait — pause for a set amount of time, or wait until the user completes another event, then continue.
Nodes are connected to each other with arrows ("edges") — exactly the same way as in the visual automation builder in the dashboard. Through the API you're essentially building the same diagram you'd build with your mouse in the dashboard, just as JSON.
How it works in a nutshell
You create an automation — the
createmethod. At this stage you only need a name; the diagram can be added later.You save the automation's diagram (graph) via
update— as a draft. A draft can be saved as many times as you like and doesn't need to be complete (for example, it can have no actions yet).Once the diagram is ready, publish it via
publish(or passactivate: truetoupdateto publish right away). Publishing runs strict validation: there must be exactly one trigger, at least one action, and all nodes must be connected to each other.A published automation runs on its own — it watches for its trigger and executes its actions. There's no need to manually run it or monitor execution through the API in this version — that happens automatically.
To temporarily turn an automation off, use
unpublish. To see the list and details, uselistandget. To delete it permanently, usedelete.
Authentication
If your API key is tied to a single bot (a regular key from the "My Bots" section — see Authorization), you don't need to specify anything else.
If you're using a key from the API Keys section that's been issued for several bots at once, every request must explicitly state which bot the automation belongs to — via the resource_key field (for POST) or query parameter (for GET). Unlike broadcast and report methods, this field is always required for automations, even if your key is tied to a single bot.
Response format
Successful response:
Error response:
The automation object
This is what's returned by the create, get, publish, and unpublish methods, and each item in list.
id
string
Automation ID
resource_key
string
The bot the automation is tied to
name
string
Name (only visible to you, in the dashboard)
status
int
Status — see the table below
trigger_type
string
Trigger type: manual, event, or schedule
graph_definition
object
The current published diagram (nodes and connections)
active_version_id
string|null
ID of the published diagram version
Automation statuses
0
Draft — not published yet
1
Active — running
2
Stopped (via unpublish)
3
Archived
4
Error
The update method additionally returns a version object — the specific diagram draft you're editing:
id
string
Version ID
workflow_id
string
ID of the automation this version belongs to
graph_definition
object
This version's diagram
version_name
string
Version name (for your own reference)
The automation diagram (graph_definition)
The diagram is a set of nodes (nodes) and connections between them (edges):
Each node has its own id (you choose it yourself — it just needs to be unique within the diagram) and a type, one of: trigger, action, condition, condition_switch, wait, wait_event. What the node actually does lives in its data field and depends on the type.
Connections (edges) define execution order: source is the node the arrow comes from, target is the node it points to.
A node also has an optional position field ({ "x": number, "y": number }) — its coordinates on the visual editor canvas. If omitted, the editor automatically lays nodes out one after another without overlapping, so you can leave position out when building a diagram via the API/an agent.
If the diagram fails validation at publish time, the response includes a list of errors:
Trigger node (trigger)
What starts the automation. The type comes from data.trigger_type:
trigger_type
When it fires
What to set in data
manual
Started manually (for testing)
—
event
When a user completes one of the selected events
event_ids — an array of event IDs from your event catalog
schedule
On a schedule
launch_frequency (day, week, month, or year), launch_time (time as HH:MM:SS)
Example — triggered by event ID 7:
Action node (action)
What to execute. The type comes from data.action_type. All text fields in actions support variables like {{user.first_name}} or {{event.value_num}} — they're automatically substituted with real values at execution time.
action_type
What it does
What to set in data
send_message
Send a message to the user on Telegram
type (sendMessage, sendPhoto, sendVideo, etc.) and message — content, same format as broadcast messages
webhook
Send an HTTP request to your server
method (GET, POST, PUT, DELETE, PATCH), url
create_event
Record a new event in analytics
resource_key, event_name
change_custom_field
Change a user's custom field
field_key, operation (set, increase, or decrease), value
amocrm / bitrix24
Create or update a deal/contact in a CRM
operation, integration_key (a pre-configured integration)
yandex_metrika
Send an offline conversion to Yandex.Metrika
integration_key, id_type, id_path, target
keitaro
Send a conversion postback to the Keitaro tracker
integration_key, subid, status
A button in message.reply_markup.inline_keyboard with "workflow_branch": true and its own "id" is marked as a workflow branch — the server fills in its callback_data and links it to a wait_event node automatically (see "Buttons that continue the workflow" below).
Integrations (amocrm, bitrix24, yandex_metrika, keitaro)
These actions use a pre-configured integration from the "Integrations" section of the dashboard — its identifier is passed in data.integration_key. The node only references the integration; credentials (domain, token, counter ID, postback key) are never stored in the graph itself.
amocrm — create or update a deal in AmoCRM.
data field
Type
Description
integration_key
string
AmoCRM integration key
operation
string
create_lead, update_lead, or upload_utm
name_template
string
Deal name template (for create_lead/update_lead), supports {{variables}}
user_fields
object
Map {amoCRM_field_id: path_or_template} — which deal fields to fill and where the value comes from
deal_id_path
string
Where to read the existing deal ID from (for update_lead/upload_utm); defaults to amo_crm.deal_id
create_if_missing
bool
For update_lead — create a deal if none is found
include_utms
bool
Mix UTM tags into the custom fields
utm_field_map
object
Map {utm_parameter: amoCRM_field_id}
dry_run
bool
Don't send the request to AmoCRM, return the request body instead (for debugging)
bitrix24 — update deal/lead/contact fields in Bitrix24 (matched to the Telegram user via the IM field).
data field
Type
Description
integration_key
string
Bitrix24 integration key
operation
string
Only update_deal is supported right now
update_targets
array
Which entities to update: deal, lead, contact (multiple allowed); defaults to ["deal"]
user_fields
object
Map {Bitrix24_field_code: template}, e.g. {"COMMENTS": "{{event.value_str}}"}
yandex_metrika — send an offline conversion via the CalibratedConversion API.
data field
Type
Description
integration_key
string
Yandex.Metrika integration key (its settings hold the counter_id)
id_type
string
Visitor identifier type: client_id, yclid, or user_id
id_path
string
Template/path to read the identifier value from, e.g. {{user.ym_client_id}}
target
string
Goal name template in Metrika
date_time_template
string
Optional — conversion time template (unix timestamp); defaults to the current time
price_template
string
Optional — conversion amount
currency
string
Optional — currency code, only used together with price_template
keitaro — send a conversion postback to the Keitaro tracker. Keitaro matches the conversion to a click by subid (click_id) and, if its own modules are configured, forwards it on to Facebook, Google Ads or TikTok — you don't need separate ad-platform integrations for that.
data field
Type
Description
integration_key
string
Keitaro integration key (its settings hold the tracker domain and postback key)
subid
string
Where to read the click_id from. It usually arrives in the bot link's start parameter and is routed into a user custom field — then this is {{user.addition_fields.keitaro_click_id}}
status
string
Conversion status: lead, sale, rejected, reg, deposit, trash, or your own
payout
string
Optional — conversion amount. Sent only if it resolves to a number
currency
string
Optional — currency code; falls back to the integration's default currency
tid
string
Optional — transaction id: lets you record a repeat conversion without overwriting the previous one
extra_params
array/object
Optional — extra parameters: sub_id_1…sub_id_30, plus em, ph, fn, ln (Keitaro forwards those to Facebook as user data). Up to 40
subid_pattern
string
Optional — a regular expression when the click_id has to be cut out of a longer string; the first capture group is used
ignore_missing_subid
bool
Optional — when the click_id is empty (organic traffic), the node succeeds and the workflow continues instead of failing
Example — send a message:
Example — send a request to your own server:
Condition node (condition)
Branches execution: if the condition is true, execution follows one path; if not, it follows another.
condition is a nested array: ["and"|"or"|"not", ...] at the top level, leaves shaped like ["operator", "field", value].
Allowed fields:
user.*
User profile fields
user.first_name, user.language_code, user.is_premium
user.custom_fields.* / user.addition_fields.*
User's custom fields, any key
user.addition_fields.keitaro_click_id
user.cohort
Cohort membership — only with in_cohort/not_in_cohort
["in_cohort", "user.cohort", 42]
events.*
Columns of the event that fired the automation
events.event_id, events.value_int
events.properties.*
Arbitrary fields from the event payload, including UTM (events.properties.utm.current — tags carried by this exact launch; events.properties.utm.last — sticky, most recent known tags)
events.properties.utm.current
Operators: and / or / not (nesting), = / != / > / < / >= / <= / like / not like (2 args: field, value), in / not in (2 args: field, array of values), between / not between (3 args: field, low, high), is (2 args: field, null), in_cohort / not_in_cohort (2 args: user.cohort, cohort id).
Branching isn't part of data — it's the edges. A condition node needs exactly two outgoing edges: one with sourceHandle: "true" (condition matched) and one with sourceHandle: "false" (condition didn't match). An edge with no sourceHandle, or the wrong one, is never picked by the execution engine — the workflow silently dead-ends at that node.
Switch-condition node (condition_switch)
Like condition, but with any number of named branches instead of two — useful when there are more than two outcomes (e.g. splitting by gender or by cohort) and a cascade of nested condition nodes would be awkward:
Each case uses the same condition format as a plain condition node (see above), with a unique id (it can't be "default" — that name is reserved). Cases are checked in array order; the first match wins.
Edges: one outgoing edge per case with sourceHandle: "case:<id>", plus an optional edge with sourceHandle: "default" for when no case matches.
Wait nodes (wait and wait_event)
wait — pause for a set number of seconds before continuing:
wait_event — pause until the user completes a specific event (event_key), but no longer than timeout minutes:
Buttons that continue the workflow (data.buttons)
Instead of a single event_key, a wait_event node can wait for a click on one of several inline buttons of a message sent by a send_message action — this is what the constructor UI calls a "button that continues the workflow", see Automations → buttons section:
In this mode event_key is not required. Each button in the message's reply_markup.inline_keyboard that's marked "workflow_branch": true with its own "id" is linked to a data.buttons entry by button_id; the server fills in event_type_id automatically when the graph is saved. The outgoing edge for each button is set as sourceHandle: "btn:<button_id>". Unlike a regular wait_event, a button-bound node never completes on timeout — it keeps listening for clicks and can fire repeatedly (a timeout just extends the wait).
Full example: event → request to server → message
Pass this object as the graph_definition field in create or update.
Methods
POST /v1/automations/create
Creates a new automation (in "draft" status by default).
Parameters
resource_key
string
yes
See "Authentication" above
name
string
yes
Automation name
trigger_type
string
no
Defaults to manual. Can be set here or later via the diagram
graph_definition
object
no
The diagram can be filled in right away or later via update
Example request
Response
POST /v1/automations/update
Saves the automation's diagram (as a draft version). If the version being edited matches the currently published one, the system automatically creates a new draft version, without touching the running one.
Parameters
resource_key
string
yes
See "Authentication" above
id
string
yes
ID of the version to edit, or "0" to create a new version
wid
string
yes, if id is "0"
Automation ID to create the new version for
graph_definition
object
no
The new diagram
version_name
string
no
Version name — for your own reference
name
string
no
New name for the automation itself
activate
bool
no
true — publish the saved version right away (with full validation, same as publish)
Example request
Response
POST /v1/automations/publish
Publishes the given diagram version — the automation starts running. Before publishing, the diagram is strictly validated: it must have exactly one trigger, at least one action, and all nodes must be connected to each other.
Parameters
resource_key
string
yes
See "Authentication" above
id
string
yes
Automation ID
version_id
string
yes
ID of the version to publish
Example request
Response
If the diagram fails validation, the response returns ok: false with a list of errors in error.validation_errors (format described in "The automation diagram" section above).
POST /v1/automations/unpublish
Stops the automation (status changes to "stopped"). No validation required — it can be stopped at any time.
Parameters
resource_key
string
yes
See "Authentication" above
id
string
yes
Automation ID
Example request
Response
GET /v1/automations/get
Returns a single automation by ID — its current status and published diagram.
Parameters
resource_key
string
yes
See "Authentication" above
id
string
yes
Automation ID
Example request
Response
GET /v1/automations/list
Returns the bot's list of automations.
Parameters
resource_key
string
yes
See "Authentication" above
project_code
string
no
Filter by project, if automations are grouped into projects
page
int
no
Page number, defaults to 1
per_page
int
no
Items per page, defaults to 20, maximum 100
Example request
Response
POST /v1/automations/delete
Permanently deletes the automation, along with all its versions. This action cannot be undone.
Parameters
resource_key
string
yes
See "Authentication" above
id
string
yes
Automation ID
Example request
Response
Possible errors
400
A required parameter is missing, or the diagram (graph_definition) failed validation at publish time
401
The API key is missing or invalid
403
The method isn't available on your plan (Premium required), the key doesn't have permission to edit automations, or the bot isn't accessible to this key
404
The automation or version with the given id wasn't found
500
Internal server error — retry the request later
Example error:
Last updated