Every change Wellknown observed on this MCP server, newest first, with what it was before and what it became. Tool-surface changes carry the definition diff. Nothing here is edited after the fact.
Changed the definition of "send_message"
⟨110 unchanged words⟩ that contact's variable context. Requires the manage_broadcasts permission. Formatting: plain text by default, so tags arrive exactly as written. Pass parseMode "HTML" to send Telegram HTML (<b>, <i>, <u>, <s>, <code>, <pre>, <a href="…">, <tg-spoiler>, <blockquote>; escape a literal <, > or & as < > &); the flow tokens [[b]]…[[/b]], [[i]], [[u]] and [[a|url]]…[[/a]] work too. Values filled in from what people typed are escaped, so they show as text and never add formatting. HTML that Telegram cannot parse is sent once more as plain text with the tags removed. Telegram bots and web chat only (web chat: not with media); refused for Instagram, mail, Telegram user accounts and SDK bots. Markdown is never rendered. Media: pass up to 10 attachments as publicly ⟨384 unchanged words⟩
⟨300 unchanged words⟩ "maxItems":10,"type":"array"},"parseMode":{"description":"Set to \"HTML\" to send the text (or caption) as Telegram HTML. Omit for plain text.","enum":["HTML"],"type":"string"},"platformId":{"description":"Platform-side user id ( ⟨54 unchanged words⟩ }` placeholders resolve against the recipient's variable context. Plain text unless parseMode is \"HTML\".","type":"string"}},"type":"object"}
Added "list_releases" and "restore_release"; changed the definition of "deploy_application" (58 tools before, 60 now)
⟨78 unchanged words⟩ application; pass botIds to publish to a subset.Rolling back toEveryanpublisholderisversionkeptisas adashboardreleaseaction(list_releases);andrestore_releaseisputs
Changed the definition of "query_flow_logs"
⟨172 unchanged words⟩ start_trigger_blank_command_catch_all, start_trigger_event_unreachable, listener_triggers_ignored, condition_rules_stored_shape, owner_consistency,http_literal_credential.http_literal_credential, flow_link_loop. Runtime warnings to search for: variable_not_found, attachment_dropped, blank_button_dropped, reply_answer_mismatch, node_ref_unresolved (the run stopped at a step the published bot does not contain), and a message that was not sent ⟨7 unchanged words⟩
Changed the definition of "apply_actions", "get_flow_example", "get_module_details" and 2 more
⟨104 unchanged words⟩ ,"delete_knowledge_base_document","import_website_into_knowledge_base","update_custom_code_file","edit_custom_code_file","patch_content"],"type":"string"},"data":{ ⟨177 unchanged words⟩
⟨40 unchanged words⟩ Defaults to false.","type":"boolean"},"locale":{"description":"Language of the bot texts inside the action batch, e.g. \"ru\", when the example has curated texts in it. Defaults to English. The guidance fields are always English.","type":"string"}},"required":["id"],"type":"object"}
Changed the definition of "query_flow_logs", "run_flow_autotest", "update_application" and 1 more
⟨113 unchanged words⟩ history, get_contact_activity with includeFlowRuns is the narrower read. Rows are redacted: URL query values read `?param=***`, HTTP request and response bodies keep their first 200 characters, and SECRET variable values read `********` — a masked value is not a missing one. Besides runtime rows, each deploy writes compile warnings (level WARNING, metadata.stage "compile", action = the kind): config_key_dropped, trigger_config_invalid, start_trigger_blank_command_catch_all, start_trigger_event_unreachable, listener_triggers_ignored, condition_rules_stored_shape, owner_consistency, http_literal_credential. Runtime warnings to search for: variable_not_found, attachment_dropped, blank_button_dropped, reply_answer_mismatch, and a message that was not sent (metadata.deliverySkipReason: owner_not_linked, owner_unreachable, peer_empty, dm_no_subject, target_unsupported).
Changed the definition of "run_flow_autotest"
⟨229 unchanged words⟩ test id. workspaceOwner: true makes that personanthe workspace's REAL owner:ofthe simulator gives them the owner's own Telegram id (the one in the workspace facts), so {{sysvar|isWorkspaceOwner}} is true for them and false for everyoneelse;else, and a message for the owner reaches them; leave platformId out for that person. A send to the owner's id or @username is a send to the owner, never to \"another user\". When no owner has linked Telegram, nobody is the owner and the owner checks fail naming the Connect Telegram step: that is expected, not a bug to fix. tags are the tag NAMES they carry, ⟨821 unchanged words⟩
Changed the definition of "run_flow_autotest"
⟨441 unchanged words⟩ steer an AI assistant block (AI_TOOL_ROUTER):itstointenttakeandonetoolofbranchesitscannotexits,besetreachedaiChoosesinona
Changed the definition of "apply_actions" and "get_block_details"
⟨306 unchanged words⟩ | conflict | permission | partial_write | unknown. update_block patches: a setting you leave out of data.data (or out of an object inside it) is KEPT; a list you send (menu.buttons, triggers, actions, media) replaces the stored list, so resend the items you keep with their ids; an explicit null clears a setting that may be empty, and is refused on data.menu, data.triggers, data.actions and data.media (send [] or the full list). A key a step does not have is refused as UNKNOWN_CONFIG_KEY with its path and the nearest real key, so one retry can fix it; a setting a step requires is refused as MISSING_REQUIRED_CONFIG_KEY. Not idempotent — resending a batch of create_* ⟨69 unchanged words⟩
⟨48 unchanged words⟩ block. Always read a block before updating it
Changed the definition of "get_variable_context"
Search variable definitions by scope andkeyword.keyword, or read one variable by id. Read-only. Returns { variables, total, returned, truncated ⟨16 unchanged words⟩ limit. Values are withheld unless includeValues is true;variablesin a list each value is cut to a 500-character preview, while variableId + includeValues returns that one value in full (read it this way before update_variable, which replaces the whole value). Variables marked secret stay redacted either way. Use the ⟨7 unchanged words⟩
⟨44 unchanged words⟩ "description":"Set true to include stored values, each: previewed to 500
Added "list_bot_chats"; changed the definition of "list_contacts" (57 tools before, 58 now)
⟨80 unchanged words⟩ for both.","type":"boolean"},"kinds":{"description":"Only rows of these kinds: \"user\" (wrote to the bot privately), \"member\" (seen in a group), \"group\" and \"channel\" (chats the bot was added to; platformId is the chat ID), \"web_chat\". Contacts recorded before kinds existed have none and match no kind. Omit for all.","items":{"enum":["user","member","group","channel","web_chat"],"type":"string"},"type":"array"},"limit":{"description":"Contacts per page, ⟨130 unchanged words⟩
List the groups and channels the application's bots were added to, newest first: title, kind, the numeric chatId a flow uses to address the chat, when the bot was added, and the bot's status and rights there (is it an administrator, can it invite or remove members). Read-only. A chat appears once the bot is added to it; when the owner's chat is missing, the bot is not in it yet. Use this instead of asking the owner for a chat ID.
Certificate changed, valid to 2027-01-11
Changed the definition of "apply_actions", "run_flow_autotest" and "validate_actions"
⟨96 unchanged words⟩ delete_broadcast","delete_variable","update_variable","create_media_from_url","create_media_from_attachment","create_knowledge_base","create_knowledge_base_text_document","update_knowledge_base_text_document","delete_knowledge_base_document"," ⟨183 unchanged words⟩
⟨71 unchanged words⟩ compiled too but are not crawled as entries. Flows that link INTO them compile too and are crawled only for a requested flow with no trigger of its own (a flow opened from a menu button is tested through the flow that opens it); a requested flow nobody can start fails with a no_entry check.","items":{"type":"string"}, ⟨890 unchanged words⟩
Added "get_tribute_setup", "list_tribute_account_products", "list_tribute_purchases" and 3 more (51 tools before, 57 now)
Read the Tribute one-time payment setup of an application: whether a Tribute account is connected, the notification link and whether the owner confirmed it, the products set up here, the number contact variables a purchase can add to, and nextSteps (what is still missing, in order; empty means ready to sell). Read-only; requires manage_automation. Start here for anything about Tribute. Three things happen in the owner's Tribute account and no tool can do them: creating the API key, creating a digital product and getting it approved by Tribute, and saving the notification link in Tribute (Dash…
List the digital products in the owner's connected Tribute account, read live from Tribute, 100 per page, newest first. Read-only; requires manage_automation. Each product says whether it can be set up (only an approved digital product can) and whether it already is. Fails with TRIBUTE_NOT_CONNECTED when no account is connected and TRIBUTE_UNAVAILABLE when Tribute does not answer. Products are created, priced and approved in Tribute, not here.
List the Tribute payments the application received, newest first, 50 per call. Read-only; requires read_payments. Each row has the payment state, the delivery state and, when delivery needs a person, the reason. An empty list means no payment notification has arrived (or no account is connected).
Changed the definition of "run_flow_autotest"
⟨103 unchanged words⟩ summary }. `passed` is false when anycheck or CONCLUSIVEscenariofailed; a scenario that failed because the simulator stood in for an AI answerfails oranisexternalunverified.callHarnessisgaps are reportedasseparatelyinconclusiveand(scenarios.scenarios[].coverageGap)
Changed the definition of "create_application", "get_action_schema", "get_application_context" and 14 more
⟨27 unchanged words⟩ :"string"},"preferredLanguage":{"description":"LanguageThefornew application's default language. It is theseededSOURCEdefaultlanguageflowsof the application's content: every block text is taken to be written in it, andthetranslationsdefaultarename.
Changed the definition of "create_follow_up_task" and "run_flow_autotest"
⟨42 unchanged words⟩ send_message or a broadcast to actually message someone. It stays open until someone completes it: a reply from the contact does not close a reminder created here (only the automatic "no reply for N days" follow-ups close on a reply). Created with a personal API key it is ⟨11 unchanged words⟩
⟨118 unchanged words⟩ this journey runs under.","properties":{"actors":{"description":"actors: who the people of this scenario are when it starts, as a list of { id, workspaceOwner?, tags? }. id is the as_contact id of the person, or \"$SELF\" for the default one. workspaceOwner: true makes that person an owner of the workspace, so {{sysvar|isWorkspaceOwner}} is true for them and false for everyone else; tags are the tag NAMES they carry, as {{sysvar|tags}} lists them. Without it nobody is the owner and nobody has a tag, so an owner-only or tag-only step can only refuse. A tag or an owner is never set with seed_var.","items":{"additionalProperties":false,"properties":{"id":{"description":"The as_contact id of the person, or \"$SELF\" for the default one.","type":"string"},"tags":{"description":"Tag NAMES this person carries when the scenario starts.","items":{"type":"string"},"type":"array"},"workspaceOwner":{"description":"true: this person is an owner of the workspace ({{sysvar|isWorkspaceOwner}} is true for them only).","type":"boolean"}},"required":["id"],"type":"object"},"type":"array"},"
Changed the definition of "get_flow_context" and "run_flow_autotest"
Return one flow's graph topology: its blocks,howintheyreadinglink,orderandfrom the start block, a short summary perblock.block, and where each block and each menu button leads (links[].to, menu.buttons[].to). Read-only. Deliberately omits block dataand, action configs and the ids of buttons, actions and links to stay cheap — once you know which ⟨19 unchanged words⟩
Changed the definition of "run_flow_autotest"
⟨427 unchanged words⟩ one builds or sends, the other seesitit; after the switch that person sees what the bot sent them earlier and can tap its buttons, and cannot tap a button on another person's screen), {\"do\":\"expect_peer_message\",\" ⟨73 unchanged words⟩
Changed the definition of "apply_actions"
⟨62 unchanged words⟩ create_flow), optionally with create_recurrence_schedule + attach_recurrence_to_broadcast forrecurring;recurring — the attach makes it live at once (it sends at the next scheduled time) when the application has an active bot, so confirm the time and audience with the user first. For a one-time broadcast, a later update_broadcast with status SCHEDULED(and scheduledAtfor one-shots)is whatactuallyschedules/sends it. The full recipe is in get_action_schema ⟨267 unchanged words⟩
Changed the definition of "update_application"
Update application-level settings (name, active state, default language, language for everyone else, incoming-message behavior). Requires the manage_settings permission in ⟨24 unchanged words⟩
⟨67 unchanged words⟩ "en\".","type":"string"},"fallbackLanguage":{"description":"Language for everyone else: the content language a contact gets when their own language is not one of the bot's languages (or unknown). Must be the default language or an enabled language; \"\" resets to the default language. Omit to leave unchanged.","type":"string"},"incomingMessageBehavior":{"description":"What happens to an ⟨75 unchanged words⟩
Changed the definition of "apply_actions", "get_action_schema", "get_design_guidelines" and 2 more
⟨197 unchanged words⟩ runs first and an invalid batch applies nothing.ExecutionIfisanNOTactionatomicfails mid-batch,howeverexecution stops and the server tries to undo the steps already applied:if`reverted:antrue`actionmeansfailsnothing
Changed the definition of "apply_actions", "run_flow_autotest" and "validate_actions"
⟨94 unchanged words⟩ delete_flow","delete_operation","delete_broadcast","delete_variable","update_variable","create_media_from_url","create_knowledge_base","create_knowledge_base_text_document","update_knowledge_base_text_document"," ⟨184 unchanged words⟩
⟨374 unchanged words⟩ the simulated user id, for owner/admin gates), {\"do\":\"as_contact\",\"id\":\"user_b\"} (every later step acts as a SECOND person — for anything two people do together: one builds or sends, the other sees it), {\"do\":\"expect_peer_message\",\"to\":\"user_b\",\"contains\":\"...\"}. A scenario with no expect / expect_var / expect_peer_message step asserts nothing.
Changed the definition of "apply_actions" and "validate_actions"
⟨101 unchanged words⟩ ,"update_knowledge_base_text_document","delete_knowledge_base_document","import_website_into_knowledge_base","update_custom_code_file","edit_custom_code_file"],"type":"string"},"data":{ ⟨177 unchanged words⟩
⟨101 unchanged words⟩ ,"update_knowledge_base_text_document","delete_knowledge_base_document","import_website_into_knowledge_base","update_custom_code_file","edit_custom_code_file"],"type":"string"},"data":{ ⟨177 unchanged words⟩
Changed the definition of "apply_actions" and "validate_actions"
⟨100 unchanged words⟩ ,"create_knowledge_base_text_document","update_knowledge_base_text_document","delete_knowledge_base_document","import_website_into_knowledge_base","update_custom_code_file"],"type":"string"},"data":{ ⟨177 unchanged words⟩
⟨100 unchanged words⟩ ,"create_knowledge_base_text_document","update_knowledge_base_text_document","delete_knowledge_base_document","import_website_into_knowledge_base","update_custom_code_file"],"type":"string"},"data":{ ⟨177 unchanged words⟩
Added "get_survey_results" (50 tools before, 51 now)
Read what customers ANSWERED in this workspace's surveys. A survey is any flow marked isSurvey: its choice questions record which option each contact tapped, and its free-text questions store the reply the contact typed. Called with NO flowId it lists every survey flow with how many people it reached, how many answered, the response rate and how many wrote a free-text answer. Called with a flowId it returns that survey per question: every option with its share of the people who answered it, and the written answers in the customers' own words. These are stated reasons, not inferred ones — the …
Certificate recorded, valid to 2026-11-12
Authorization not required
First tool surface recorded: 50 tools (server version 0.1.0)
Showing the latest 28 events. The API returns up to 500 and filters by kind: ?kind=tool_surface_changed
List the application's releases, newest first. A release is a frozen copy of everything the editor held when it was published (flows, steps, menus, actions, variables), stored with the rows' own ids. Each entry has its number, when and how it was made (DASHBOARD, MCP, AI_REPUBLISH, BOT_CREATE, or RESTORE_SAFETY: the editor saved right before a restore), an optional note, flow and step counts, and liveBotIds: the bots whose last publish was this release. Use restore_release to put one back. Requires view access.
Put an earlier release back into the editor: every flow, step, menu, action and variable returns exactly as it was, under the same ids, so running conversations, scheduled steps and buttons users already received keep working. Nothing is lost: the current editor state is saved first as a RESTORE_SAFETY release, or, when it already equals a recent release, that release is reused (either way returned as safetyReleaseNumber); restoring that one undoes this. Steps added since are soft-deleted, so their message history and contacts' stored values stay. Values the bot itself keeps (application vari…
⟨67 unchanged words⟩ string plus `availableModules` listing valid keys and versions. The answer opens with actionIndex (every action, one line each); pass actions to read only some, and read omittedActions when not every action fit.
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"actions":{"description":"Action template keys to read in full, from the answer's actionIndex. Omit for every action that fits; the ones that do not fit are named in omittedActions.","items":{"type":"string"},"type":"array"},"applicationId":{"description":"Application (workspace) id. ⟨83 unchanged words⟩
⟨140 unchanged words⟩ to real users and no state is written. An outside GET call no scenario fixture answers is answered from a recorded real response: one the server itself fetched for this application in the last 24 h (the endpoint check apply_actions runs), used only for exactly the same address and query values. `outsideCalls` says how many calls were answered that way, how many stayed coverage gaps, and when each answer was recorded.
⟨747 unchanged words⟩ literal journey value\"] strengthens message/notification checks only. An expect_check about someone other than the acting person (an outcome for person \"other\") needs \"other\": \"<as_contact id>\", the id that person has in this scenario (\"$SELF\" is the first person, once another one acts); e.g. {\"do\":\"start\",\"command\":\"/start\"}, {\"do\":\"tap\",\"button\":\"Apply\"}, {\"do\":\"as_contact\",\"id\":\"admin\"}, {\"do\":\"tap\",\"button\":\"Approve\"}, {\"do\":\"expect_check\",\"checkId\":\"c2\",\"other\":\"$SELF\"}. Each step is one object keyed by `do`: ⟨145 unchanged words⟩ :[\"text that must NOT appear\"]} (expect needs anyOf: a list of at least one verbatim fragment of what the bot sends after the action right before it; not (texts that must NOT appear) is optional and is checked only beside anyOf, because an expect with only not passes when the bot says nothing; a text in anyOf or not that the bot cannot send is removed: a {{…}} template, an internal id (no spaces, joined by _ . : or -), and, when the bot's texts are known, a button label or words it never writes; a removed text makes the scenario an invalid test), {\"do\":\"expect_var\",\"name\ ⟨239 unchanged words⟩
⟨104 unchanged words⟩ ,"delete_knowledge_base_document","import_website_into_knowledge_base","update_custom_code_file","edit_custom_code_file","patch_content"],"type":"string"},"data":{ ⟨177 unchanged words⟩
⟨292 unchanged words⟩ string"},"incomingMessageFlowId":{"description":"Flow of this application to run for unmatched inbound messages. Requiredin practicewhen incomingMessageBehavior is EXECUTE_FLOW.","type":"string ⟨32 unchanged words⟩
⟨73 unchanged words⟩ ). Setting status to "unsubscribed" stops broadcasts, sequences andsequencesdirect sends for the contact. Setting it back to "subscribed" works only when a person on the team unsubscribed them; a contact who blocked the bot or used an unsubscribe link is refused with 409 and comes back only by writing to the bot again.
⟨96 unchanged words⟩ delete_broadcast","delete_variable","update_variable","create_media_from_url","create_media_from_attachment","create_knowledge_base","create_knowledge_base_text_document","update_knowledge_base_text_document","delete_knowledge_base_document"," ⟨183 unchanged words⟩
Queue one Tribute payment for delivery again, for a payment that was paid but not delivered. Requires recover_payments. It queues, it does not deliver in the call: read list_tribute_purchases afterwards. Refused with TRIBUTE_REVIEW_REQUIRED for a payment that has a reviewReason.
Set up a product of the connected Tribute account for sale in this application, or change one already set up (one saved product per Tribute product, so calling it again updates). Requires manage_automation. Returns the saved product; its id is the productBindingId of a Payment block with provider TRIBUTE. A purchase always runs the Paid branch of that block; adding a number to a contact variable is optional. Once the product is published, what it adds is fixed (TRIBUTE_IMMUTABLE_BENEFIT): to change it the owner creates a new product in Tribute. Messages stay editable.
Connect a Tribute account to the application or change the connection. Requires manage_settings. Pass at least one field; they are applied in the order apiKey, notificationsConfirmed, paused. Returns the same view as get_tribute_setup. The API key is stored encrypted and no tool returns it. Three things happen in the owner's Tribute account and no tool can do them: creating the API key, creating a digital product and getting it approved by Tribute, and saving the notification link in Tribute (Dashboard → Settings → API Keys → Webhook URL).
⟨135 unchanged words⟩ starts, as a list of { id, platformId?, workspaceOwner?, tags? }. id is the as_contact id of the person, or \"$SELF\" for the default one. platformId is an exact numeric Telegram user id for bots that compare a literal id; omit it to derive a stable test id. workspaceOwner: true makes that person an owner of ⟨19 unchanged words⟩ carry, as {{sysvar|tags}} lists them.Without it nobody is the owner and nobody has a tag, so an owner-only or tag-only step can only refuse.A tag or an owner is never set ⟨19 unchanged words⟩ default one.","type":"string"},"platformId":{"description":"Exact numeric Telegram user id, for example the id a legacy admin gate compares against.","pattern":"^[1-9]\\d{0,15}$","type":"string"},"tags":{"description":"Tag NAMES this person ⟨7 unchanged words⟩ :"string"},"type":"array"},"telegramMembership":{"description":"What getChatMember reports for this actor; overrides the scenario-wide membership.","enum":["member","not_member"],"type":"string"},"workspaceOwner":{"description":"true: this person ⟨101 unchanged words⟩ or not.","type":"string"},"httpResponses":{"description":"Mock outside HTTP calls for this scenario. These are local responses; no request is sent to the service.","items":{"additionalProperties":false,"properties":{"body":{"description":"JSON body returned to the bot code."},"method":{"description":"Optional uppercase HTTP method to match.","type":"string"},"networkError":{"description":"Reject the request with this transport error instead of returning an HTTP response.","type":"string"},"requestBodyContains":{"description":"Optional literal substring required in the outgoing request body.","minLength":1,"type":"string"},"status":{"maximum":599,"minimum":100,"type":"integer"},"times":{"description":"Answer at most this many matching calls, then use the next fixture.","exclusiveMinimum":0,"type":"integer"},"urlPattern":{"description":"Substring of the outgoing URL to match.","minLength":1,"type":"string"}},"required":["urlPattern"],"type":"object"},"maxItems":12,"type":"array"},"telegramMembership":{"description":"What a Telegram membership ⟨310 unchanged words⟩ ":\"user_b\",\"contains\":\"...\",\"mediaType\":\"IMAGE\"} (mediaType is optional; assert proof photos/files on the same peer message), {\"do\":\"expect_http_request\",\"urlContains\":\"/orders\",\"method\":\"POST\",\"bodyContains\":\"orderId\",\"count\":1} (assert the outgoing request; method, bodyContains and count are optional). A scenario with no expect / expect_var / expect_peer_message step asserts nothing. At most 15 steps; malformed or truncated stepsaremakedroppedtheratherscenariothananfailinginvalidthetest,run.never a pass.","items":{"additionalProperties":{},"type ⟨37 unchanged words⟩
ReturnRead-only,theneeds no API key. The action-authoring contractthatapply_actions batches are validated against.Read-only, needs no API key. Called withWith NO argumentsit, returnsa compactan INDEX:every creatableof blocktypetypes, actions, action kinds andtopictopics withone line saying when you need it. Call itdescriptionsaandsecondsizes.timeThennamingrequest only whatthethis botyouuses.areDetailbuildingresponsesactuallyincludeusesessential—rules{andblockTypes:basic["AI_TOOL_ROUTER"],shapes;topics:follow["knowledgeBases"]`seeWhen`}before—usingandspecializedyoufeatures:gettemplateExpressionsthoseforcontractscomputedinCELfullexpressions,plusgroupVariablestheforbatchsender/chatcontract,variableplaceholderownership,rulestriggerDetailsandforthewebhook/moduleinvariantseventsthatandapplytriggertooutputeverymappings.batch.ResponsesThereturn wholedocument issectionsfarwithintoothelargebudget.toRequestread`omitted`atnamesonce;again;the`alsoRelevant`indexlistsexistsreferencedsotopicsyouthatneverdidhavenotto.fit.
⟨76 unchanged words⟩ "Leave this out on your FIRST detail call:that call must return the batchtocontract,receive placeholder rules and always-oninvariants (~9k characters), andinvariants; the indexdoesreportsnottheircontainsizethem.as coreChars. Pass false only on LATER detail calls in the same session,to avoidafter receivingthemthoseagain.rules.","type":"boolean"},"topics":{ ⟨22 unchanged words⟩
⟨50 unchanged words⟩ only in the operations list, never in flows. application.blockFallbackStrategy / blockFallbackEnabled / blockFallbackFlowId are the application-level defaults for what a failed action does in an ACTION block that sets none of its own — the actionFailure topic of get_action_schema says how they interact with a Failure link.
⟨11 unchanged words⟩ linked flow, and delivery breakdown by status. recipientCount is the number of delivery rows once the broadcast has started sending. Before that it is a live count of the audience only when the audience has no filter. null means NOT COMPUTED, never zero: a filtered audience is evaluated when the broadcast sends, and get_broadcast_details reads delivery rows only, so it is null for every broadcast that has none yet. Read-only. Call list_broadcasts first to find the broadcastId. ⟨7 unchanged words⟩
⟨38 unchanged words⟩ action configs and the ids of buttons, actions, links andlinkscondition rules to stay cheap, and returns message text and condition operands only as cut *Preview fields (textPreview, firstOperandPreview, valuePreview) that are for reading, never for writing back — once you know which block matters, ⟨17 unchanged words⟩
⟨40 unchanged words⟩ an `automatic` item closes itself when its conditionclearsclears;andupdate_pulse_item cannotbe`resolve`closedit,byonlyhand.`acknowledge` it (close it as seen).
⟨19 unchanged words⟩ counts report messages attempted, not confirmed deliveries. recipientCount is the number of delivery rows once the broadcast has started sending. Before that it is a live count of the audience only when the audience has no filter. null means NOT COMPUTED, never zero: a filtered audience is evaluated when the broadcast sends, and get_broadcast_details reads delivery rows only, so it is null for every broadcast that has none yet. Use get_broadcast_details for one broadcast's full breakdown. To ⟨21 unchanged words⟩
⟨78 unchanged words⟩ :"Broadcasts per page, between 1 and 100. Defaults to 10.","maximum":100,"minimum":1,"type ⟨14 unchanged words⟩ {"description":"Only broadcasts in this lifecyclestate.state (FAILED = the send broke and did not finish). Omit for all states.","enum":["DRAFT","SCHEDULED","QUEUED","SENDING","SENT","PAUSED","CANCELLED","FAILED"],"type":"string"}},"type":"object"}
⟨255 unchanged words⟩ this time (ISO 8601 date string). Applies to every kind; for BROADCAST_DELIVERED the event time is when that contact's delivery was sent. Omit for the whole history — that is ⟨13 unchanged words⟩
⟨25 unchanged words⟩ follow-up sends nothing by itself. Scopes: `mine` is the open work assigned to the key's owner and needs a personalAPI key,key; `unassigned` is unownedwork,open work; `team` iseverything,all open work; `completed` is closedhistory;history.without`unassigned`, `team` and `completed` reach past the caller's own tasks ONLY for an owner or admin of the application, or a workspace API key. For any other personal key `unassigned` and `team` return the same as `mine`, and `completed` returns only their own closed tasks — the result's `scope.narrowedToOwn` is true when that happened. Without a scope a personal key reads `mine` and ⟨21 unchanged words⟩
⟨93 unchanged words⟩ work to list. `mine` requires a personal API key; `unassigned`, `team` and `completed` widen past the caller's own tasks only for an owner, an admin or a workspace key.","enum":["mine","unassigned", ⟨41 unchanged words⟩
⟨16 unchanged words⟩ ). Read-only, needs no API key. Returnscompactsummariesmatchesto choose by — id, title, summary, useWhen, tags, requiredModules, hasSchemaExample — with no flow body; pass an id ⟨28 unchanged words⟩
⟨9 unchanged words⟩ examples to return, between 1 and 8. Defaults to 3. Values outside that range are rejected.","maximum" ⟨22 unchanged words⟩ :"string"},"tags":{"description":"ArrayFilter:ofonlytagexamplesstringscarryingtoatfilterleastbyONE of these tags are returned, e.g. [\"payments\",\"onboarding\"].CombinedWithwitha query,whenthe query ranks within that set (botharemustgiven.match). When no example carries any of them the result is empty and lists `knownTags`.","items":{"type":"string"}, ⟨4 unchanged words⟩
⟨64 unchanged words⟩ because blocks store variable ids, not names. `truncated` is true whenever a limit dropped something, and `cappedBy` names which: FLOW_LIMIT (more flows matched than `limit`), ROW_LIMIT (the 1000-match ceiling was hit; lower-ranked matches were not read), MATCHED_VARIABLES (the keyword matched more than 25 variable names — only the 25 closest, shortest name first, are resolved to the blocks that reference them, so blocks reading the others are MISSING), MATCHES_PER_FLOW (a flow lists at most 12 matches; its matchCount is the real number), MATCHES_PER_BLOCK (a block lists at most 3). A truncated answer is not proof that nothing else matches: narrow the keyword, or search the full variable name, before you rename or remove something on the strength of it. Use this instead of walking flows with get_flow_context ⟨28 unchanged words⟩
⟨53 unchanged words⟩ above 100 are clamped to 100. Check `truncated`toanddetect`cappedBy`:athiscut-offisresultonlyset.one of the limits that can cut the answer.","maximum":100,"minimum":1,"type ⟨38 unchanged words⟩
⟨161 unchanged words⟩ , not just the absence of an error. An unsubscribed contact, or a contact whose bot is not active, is refused — the same rule send_message applies. Nothing is queued for it; its row has `ok: false`, the reason in `error`, and `refused` set to `contact_unsubscribed` or `bot_inactive`. A sleeping bot is not refused: it is woken first. BROADCAST and OPERATION flows are rejected — a ⟨87 unchanged words⟩
⟨162 unchanged words⟩ the URL has none. Not supported for SDKbots.bots or for Telegram user-account bots (telegram_mtproto, text only) — the call is rejected and nothing is sent. Buttons: up to 8, each carrying EXACTLY ⟨82 unchanged words⟩ (taps never reach the runtime there). Buttons of either kind are rejected for telegram_mtproto bots: a user account cannot send buttons, so put the link in the text. To send a WHOLE flow as the message ⟨30 unchanged words⟩ the send, not that the platform delivereditit. A send that fails afterwards (a broken media URL,surfacesaincontactthethatflowblockedlogsthe bot, a chat not found) is not returned here: it is written to the flow logs as an error row for that contact with action `direct_message` (read it with query_flow_logs or get_contact_activity)., and no outgoing message is added to the transcript. Unsubscribed contacts and inactive bots are rejected. A telegram_mtproto bot (a Telegram user account) sends nothing until its owner turns on "Sending from this account" in the dashboard (Bot settings → Account). It is OFF for every newly connected account and no tool changes it. While it is off the call is rejected, except to the account's own Saved Messages (platformId "me"). NOT idempotent and not reversible — each call ⟨31 unchanged words⟩
⟨41 unchanged words⟩ Each entry needs a chatId (e.g. "-100…") or a public username/t.me link,forandchatsit must be a chat the account has JOINED: only joined)orchats can be watched. Watching a publicusername/t.mechatlink;withoutmodejoining"joined"it(default)isprocessesnot available — an entry for a chat the account is not in,"public_peek"is(maxsaved10,butneedsnever produces ausername)message,pollssoajoinpublicthe chatwithoutwithjoining.the account first. The running userbot picks the change up within ⟨18 unchanged words⟩
⟨95 unchanged words⟩ :"string"},"mode":{"description":"Always \"joined\" (default)the=default,passivemayupdatesbeforomitted): a chat the account isin; \"public_peek\" = pollapublicmemberchatof.withoutNojoiningother(maxmode10).exists.","enum":["joined","public_peek"],"type":"string"},"title":{ ⟨12 unchanged words⟩ ":{"description":"Public @username or t.melink.
⟨16 unchanged words⟩ everything the account already talks to becomes avalidcontact send_message can target without waiting for each chat to message first. Importing does not allow sending: send_message to these contacts is rejected until the account's owner turns on "Sending from this account" in the dashboard (OFF by default, no tool changes it), and then it sends text only — no media, no buttons. Requires the manage_broadcasts permission. Reads the account's dialog ⟨60 unchanged words⟩
⟨42 unchanged words⟩ :"string"},"defaultLanguage":{"description":"DefaultNew default language. It is the SOURCE languageforofnewtheflows.application'sOnlycontent: every block text is taken to be written in it, and translations are made from it. Any ISO 639 base language tag is accepted and normalised to its lowercase base form (\"en\de\", \"ru\pt-BR\",and→ \"es\pt\");areasupported;valueanythatotherisvaluenot a 2-3 letter tag (for example \"german\") is rejected with INVALID_LANGUAGE — nothing falls back to \"en\". Changing it translates NOTHING: the texts already written are simply treated as written in the new language from then on, and the new default is dropped from the list of additional languages. Omit to leave unchanged.","type":"string"},"fallbackLanguage":{ ⟨65 unchanged words⟩ operator, EXECUTE_FLOW runs the flow named by incomingMessageFlowId. Side effect of EXECUTE_FLOW: the platform also adds an \"any message\" MESSAGE trigger with originModuleKey \"incoming_message_behavior\" to that flow's start block, and removes it when this setting moves to another flow or back to LIVE_CHAT. It is system-owned: when you later resend that block's triggers with update_block, resend it unchanged with its id.","enum":["LIVE_CHAT","EXECUTE_FLOW"], ⟨52 unchanged words⟩
⟨33 unchanged words⟩ from every member and records who decided that. `acknowledge` closes an attention item as seen, with no reason and no note — it is the only hand-close an `automatic` item accepts. `resolve` closes with a resolutionCode and is refused for an `automatic` item. Both need the permission for the item's source (manage_broadcasts for a broadcast, manage_automation for a flow, sequence or operation), and a critical item that is not `manual` by policy can be closed only by an owner or admin (a workspace key counts as owner); `resolve` on such an item also needs a note. Closing a card does not fix its cause, and it hides the problem:aandetectoritemthatclosed by hand is NOT raised again for 14 days, even while its detector still observes theconditioncondition.raisesOnly an anomaly theitemplatformagainclosedonitselfits(resolutionCodenext`source_condition_cleared`)sweep,reopensandataonce when the condition returns. A dismissed recommendation returns by itself after the same cooldown. Does not apply a recommendation's proposed change ⟨6 unchanged words⟩
⟨6 unchanged words⟩ {"action":{"description":"acknowledge: closeitan attention item asseen.seen (the only hand-close an `automatic` item accepts). resolve: close it with areason.reason (refused for an `automatic` item). dismiss/restore: hide or unhide a recommendation for the ⟨70 unchanged words⟩ Free-text note stored with a `resolve`. Required whenoverridingresolving a criticalitem.item that is not `manual` by policy. Ignored by `acknowledge`, which stores no note.","type":"string"},"reason":{ ⟨71 unchanged words⟩
⟨258 unchanged words⟩ the reply to the action right before it. When accepted checks are supplied, use {\"do\":\"expect_check\",\"checkId\":\"<accepted id>\"} for their outcomes; the server selects the observation channel. Optional contains:[\"literal journey value\"] strengthens message/notification checks only. Each step is one object keyed by `do`: ⟨265 unchanged words⟩
⟨71 unchanged words⟩ :"string"},"type":"array"},"includeCore":{"description":"Leave this out on your FIRST detail call: that call must return the batch contract, placeholder rules and always-on invariants (~9k characters), and the index does not contain them. Pass false only on LATER detail calls in the same session, to avoid receiving them again.","type":"boolean"},"topics":{"description":"Topics whose rules you ⟨17 unchanged words⟩
⟨22 unchanged words⟩ must be wired, and worked examples. Read-only,takesneeds no API key. Called with NO arguments it returns a compact INDEX: the short rules every batch needs, in full, plus every other section andneedsexamplenowithAPIonekey.line saying when you need it. Call it a second time naming only the ones this change touches — { sections: ["flow-link-navigation","example-flow-link-navigation"] } — to get them in full. Read this before any structural edit (new ⟨23 unchanged words⟩
{"$schema":"http://json-schema.org/draft-07/schema#","additionalProperties":false,"properties":{"examples":{"description":"Example ids from the index. Same as listing them in sections.","items":{"type":"string"},"type":"array"},"sections":{"description":"Section and example ids from the index whose full text you need (e.g. [\"input-collection\",\"example-explicit-listener\"]).","items":{"type":"string"},"type":"array"}},"type":"object"}
⟨161 unchanged words⟩ "enum":["INFO","WARNING","ERROR","DEBUG"],"type":"string"},"limit":{ ⟨51 unchanged words⟩
⟨175 unchanged words⟩ test compares against (e.g. \"hot\"). It does NOT steer an AI assistant block (AI_TOOL_ROUTER): its intent and tool branches cannot be reached in a test, pinned or not.","type":"string"},"telegramMembership":{ ⟨305 unchanged words⟩
⟨94 unchanged words⟩ delete_flow","delete_operation","delete_broadcast","delete_variable","update_variable","create_media_from_url","create_knowledge_base","create_knowledge_base_text_document","update_knowledge_base_text_document"," ⟨184 unchanged words⟩