Flow triggers and nodes
Every way a flow can start, every kind of step it can run, and how a step reads what came before it.
Updated October 2026Flows2 of 3
Short answer
{{ steps.<id>.output }} templates, and runs under the identity you choose per step.Triggers
Drag a trigger from the palette onto the canvas, or start from a template that already has one. A trigger fires the published version of the flow; edits to the draft do not change what fires until you publish again.
| Trigger | What starts a run | What you configure |
|---|---|---|
| schedule | A cron expression fires in the time zone you pick. | Five-field cron, IANA time zone (UTC by default), and what to do with a missed firing: skip it or run once. |
| webhook | An HTTP request reaches the trigger's hook URL. | Body format (JSON or form), an optional field map onto trigger.* names, and a sample request captured with Listen. |
| event | Something happens on the platform: a run finishes, a document is indexed, a Slack message arrives, an RSS feed has a new item. | The event name, an optional filter condition, and the feed URL for rss.item. |
| agent | An agent calls the flow as a tool during a chat. | The tool name, a description the agent reads, which agents may call it, and how long the tool waits inline (up to 60 seconds). |
| manual | You press Run, or an API key starts the run. | Nothing. The run form is built from the flow's input schema. |
Schedule
Type a cron expression or plain words such as every weekday at 9; the inspector shows the next three firings so you can check it. The time zone is an IANA name, UTC when you leave it empty. Your plan sets the shortest interval a schedule may use; a schedule tighter than that is a readiness problem and blocks publishing. If the platform was down when a firing was due, the missed-run policy decides whether it is skipped (the default) or run once on recovery.
Webhook
Each webhook trigger gets its own URL, /api/flows/hooks/<triggerId>, and a secret you rotate from the inspector; the secret is shown once, and only its last characters stay visible afterwards. Every request must be signed:
POST /api/flows/hooks/<triggerId>
Content-Type: application/json
x-akili-signature: t=1760250000,v1=<hex HMAC-SHA256(secret, "<t>.<raw body>")>
{ "customer": "cus_123", "amount": 4900 }tmust be within 300 seconds of the server clock, and a signature seen again within 600 seconds answers 409, so a replayed request never starts a second run.- A valid request answers
202with the run id. Send anIdempotency-Keyheader to make a retried delivery return the first run instead of starting another. - The payload reaches your steps as
trigger.body,trigger.headersandtrigger.receivedAt. Add a field map (for examplecustomer → body.data.customer_id) to expose only the names you need astrigger.customer. - Press Listen to open a ten-minute window: the next signed request is stored as the trigger's sample and does not start a run, and the sample feeds step tests.
Event
Pick one platform event; an optional filter expression over trigger.* skips firings that do not match. The events available today:
message.completedcredit.thresholdspend_cap.warningwebchat.spend_cap.warningflow.run.completedflow.run.failedknowledge.document.indexedstripe.checkout.completedstripe.subscription.updatedstripe.subscription.deletedstripe.invoice.payment_failedslack.messagesocial.post.metrics_updatedrss.item
For rss.item you also give a feed URL; a poller checks it every 15 minutes. Events the catalog lists as not yet available show as such in the palette and are a readiness problem if a draft uses them.
Agent
An agent trigger turns the flow into a chat tool. Give it a snake_case tool name (reserved and already-taken names are refused at publish), a description the agent reads to decide when to call it, and the agents that may call it (up to 50). The tool waits inline for up to 60 seconds; a run that takes longer answers with its run id, and the agent can read the result later with the shared flow_status tool. A flow started this way shows its run summary and any approval card in the chat that started it.
Manual
Define the flow's inputs as a JSON Schema and the Run bar builds a form from it. A manual run is attributed to the person who started it, which is what lets steps use your personal connections. API keys with the flows:run scope start manual runs through POST /flows/:id/runs, 60 per minute.
Nodes
The palette lists every node with a readiness state for you: ready, needs a connection, not in your plan, not granted to you, or not available in this deployment. Every node can set a timeout and retries (0 to 5 extra attempts, fixed or exponential backoff), and every node has a failure handle you can wire to an error branch.
Agents and tools
| Node | What it does | What you configure |
|---|---|---|
| agent.turn | Runs one headless turn of an agent with your instructions as the user message. | Agent, instructions, optional output schema for a structured result, credit cap, timeout (90 s by default), retries, runs-as. |
| agent.council | Puts a question to a council: several models answer, an adjudicator synthesises, fact-checking on by default. | Question, council, optional roster override (up to 8 seats), fact-check toggle, timeout. |
| run_skill | Runs an agent turn with one skill attached, the way a / command does in chat. | Skill and version (latest approved by default), agent, arguments, credit cap, timeout, retries, runs-as. |
| tool.call | Calls one platform tool directly: web_search, url_fetch, code_interpreter and the others in the tool catalog. | Tool, arguments, timeout, retries, optional runs-as (inherits the run's when unset). |
| mcp.call | Calls one tool on an MCP server connected to your workspace. | Server, tool name, arguments, timeout, retries, runs-as. |
App actions
app.action is one node with a connector, an action and the action's parameters. The launch actions:
| Action | Connector | What it does |
|---|---|---|
| gmail.send | Google Workspace | Send an email from the connected mailbox. |
| calendar.createEvent | Google Workspace | Create a calendar event. |
| docs.create | Google Workspace | Create a Google Doc from text you give it. |
| drive.search | Google Workspace | Search Drive and return matching files. |
| slack.postMessage | Slack | Post a message to a channel. |
| slack.addReaction | Slack | Add an emoji reaction to a message. |
| slack.getMessage | Slack | Read one message. |
| teams.reply | Microsoft Teams | Reply in a Teams thread. |
An app action runs as the flow owner (your own connection, manual runs only) or as an agent that holds a connection for that app. Readiness checks that the connection exists, belongs to the agent, is for the right app and was granted the scopes the action needs. Other Microsoft 365 and Dataverse actions go through mcp.call for now.
Content and messaging
| Node | What it does | What you configure |
|---|---|---|
| studio.create | Generates Studio content from a brief and waits for the job (180 s by default). | Content type, brief, optional template, timeout. |
| studio.social_draft | Drafts a social post per channel with Akili, charged like an AI draft in Publish. | Channels (1 to 40), brief, tone, optional timeout. |
| knowledge.ingest | Adds a document to one of the flow owner's knowledge bases. | Knowledge base, and the source: text, a URL or a file. |
| social.repost | Reposts a published release on one of the workspace's channels (X, Bluesky, Mastodon, Threads). | Channel and release id, usually a template over the trigger payload. |
| social.comment | Replies to a published release; charged like a published item. | Channel, release id, text. |
| http.request | Calls any HTTP endpoint. | Method, URL, headers, body, timeout (up to 120 s), retries. |
| notify.send | Sends a message in-app, by email or to an organization webhook. | Channel, recipients (members, email addresses, webhook ids, or owner), subject, message. |
Logic and other flows
| Node | What it does | What you configure |
|---|---|---|
| logic.condition | Evaluates an expression and takes the yes or the no edge. | An expression such as steps.research.output.impact == "high". |
| logic.loop | Runs the each branch once per item of an array, then continues on done. | The path to the array, concurrency (up to 5), maximum items (up to 1000). |
| logic.transform | Runs a small JavaScript function in a sandbox and returns what it returns. | Code, named inputs resolved from templates, timeout (up to 30 s). |
| logic.wait | Parks the run for a duration or until an instant. | Duration and unit, or an ISO-8601 time; 30 days at most. |
| logic.approval | Parks the run until a named person decides, then takes the approved, rejected, changes_requested or expired edge. | Approvers (members or a role), fallback person, deadline (5 minutes to 30 days), the message approvers read. |
| flow.call | Starts another flow as a child run. | Flow, input, whether to wait for the child's output (timeout up to 3600 s). |
A condition's edges are yes and no; a loop's are each and done; an approval's are its four outcomes. An outcome with no edge is a readiness problem, because the run would fail the moment it was taken.
Pass data between steps
Any text field in a node accepts {{ path }} tokens, resolved when the step runs. The path starts from one of five roots:
trigger— what started the run: the webhook body and headers, the event payload, or the agent's arguments. With no payload it is the trigger kind and the time it fired.inputs— the manual run form, or the input a parent flow passed in.steps.<id>— an earlier step'soutput,statusandcredits. Node ids are letters, digits, underscores and hyphens; rename a node and its id stays.runandenv— the run's own metadata and the values the platform exposes.
Summarise this for {{ trigger.body.customer }}: {{ steps.fetch.output | json }}
Due {{ steps.plan.output.dueDate | date }} — {{ steps.tags.output | join }}
{{ inputs.channel | default }}Four filters follow a pipe: json serializes an object, date formats an instant, default substitutes a fallback and join flattens an array. A field that is exactly one token keeps the value's type, so an array or an object passes through intact rather than as text. A step's output above 1 MB fails the step rather than being truncated.
Runs-as: whose identity a step uses
Agent turns, skills, tool calls, MCP calls and app actions have a Runs as field in the inspector with three tiers:
- Owner (the default) — the flow owner's credentials and connections. Fine for manual runs; for unattended triggers it only works where the workspace, not you personally, provides the credential.
- Agent — the agent's own credential, granted to it in the agent builder. This is what makes a scheduled, webhook or event-driven flow able to send mail or post to Slack.
- Workspace — a workspace-level credential. App actions have no workspace connections yet, so readiness refuses that combination.
A tool call with no runs-as inherits the run's, so a tool step in an agent-triggered run keeps running as the agent. When no credential of the chosen tier can serve a step unattended, the inspector shows a readiness problem that names the tool, the tier and the reason, and publishing is refused until you fix it.
Good to know
- A step that no trigger reaches. Readiness flags it, because it would be skipped on every run. Wire it in or delete it.
- Default instructions left on an agent step. An advisory reminds you the step still carries the palette's placeholder; it does not block publishing.
- Loops and credits. A loop runs its branch once per item, so a credit cap on the step inside the loop, not on the flow, is what bounds the spend.
- Tools that only the owner can own. Image generation and canvas tools run as the owner only, because an agent or the workspace cannot own the file they produce.
- Reading the other pages. Flows covers the builder, publishing and limits; Runs and approvals covers what happens after a trigger fires.
Frequently asked questions
Can a flow have more than one trigger?
Yes. Each trigger is a node on the canvas, and a run records which trigger started it. The Fire once now action in the trigger inspector works for manual, schedule, webhook and event triggers; an agent trigger is fired by the agent's tool.
How does an agent start a flow?
Give the flow an agent trigger with a tool name and a description, and grant the agents that may call it. In chat, the agent sees the flow as a tool and starts it when the conversation calls for it; the person chatting needs permission to run flows, and an agent starts at most three flows per turn.
Why does my webhook return 401?
The request is not signed, or the signature is stale. Sign the raw body with the trigger's secret using the x-akili-signature scheme, keep the timestamp within five minutes of the server clock, and do not resend the same signature within ten minutes.
Which app actions can run on a schedule?
Only app actions that run as an agent with its own connection. An action set to run as the flow owner uses your personal connection and is allowed on manual runs only; readiness refuses to publish it behind a schedule, a webhook or an event.
What is the difference between a template token and a condition?
A template token is written in double braces inside any text field and is replaced by a value when the step runs. A condition is a bare expression without braces, evaluated by the same resolver to true or false; it is never run as JavaScript.