Flows API
Create, update, and execute automation flows. Manage flow configurations and view execution history.
Endpoints
/api/v1/flow/createCreate a new automation flow
Parameters
name | stringrequired | Name for the new automation flow |
description | string | Optional description of the flow |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/create \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"name": "example",
"description": "example"
}'/api/v1/flow/listList all automation flows. Returns array with id, name, description, isActive, triggerType, nodes[], edges[].
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/list \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{}'/api/v1/flow/getAvailableNodesGet available node types for building flows. Use type filter to reduce response size.
Parameters
type | string | Filter by node type. "connectors" = the user's own MCP connectors (Automations → Connectors) and their tools, added as connector steps |
category | string | Filter utilities/tools by category. For connectors: a tool group — a platform tool's router such as "tables" or "flow", or a user connector's slug — and switches the connectors answer to full detail |
mcpServerId | string | Filter tools by specific MCP server |
connectorId | string | Connectors: only this connector (a connectorId from a previous call, or "platform:serenities" for the built-in Serenities tools); switches the connectors answer to full detail |
toolNames | array | Connectors: load exactly these tools WITH their inputSchema, by name or toolName (e.g. ["tables_createRow", "gmail_send_message"]). The cheap follow-up to the compact index |
search | string | Search by name or description. For connectors this switches to full detail (inputSchema) for the matches |
limit | number | Max items for tools, and for full-detail connector tools (default 50) |
offset | number | Offset for tools / full-detail connector tools pagination |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getAvailableNodes \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"type": "example",
"category": "example",
"mcpServerId": "example"
}'/api/v1/flow/getByIdGet flow details with nodes and edges
Parameters
id | stringrequired | Flow ID from list |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getById \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"id": "example"
}'/api/v1/flow/updateUpdate flow configuration. Only provided fields are updated.
Parameters
id | stringrequired | Flow ID from list |
name | string | New name for the flow |
description | string | New description |
nodes | array | Array of flow nodes (at most 1000) |
edges | array | Array of flow edges connecting nodes (at most 5000) |
triggerType | string | Trigger type: "manual", "webhook", "schedule", "table" |
isActive | boolean | Whether the flow is active |
usedSequenceNumbers | array | Used sequence numbers for node ordering |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/update \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"id": "example",
"name": "example",
"description": "example"
}'/api/v1/flow/updateNodeConfigUpdate one node's configuration in place (no need to resend the whole flow). Read the node's current config with getById first; get per-node-type config shapes from getAvailableNodes and getHelp.
Parameters
flowId | stringrequired | Flow ID |
nodeId | stringrequired | Node ID within the flow (from getById — node ids live in the nodes array) |
config | objectrequired | The node's config object — REPLACES the node's existing config, so read the current config via getById first and send the full merged object. The shape depends on the node type: call getAvailableNodes (and getHelp for worked examples) to see each type's config fields. Values support {{template}} references to prior node outputs, e.g. {{#2.email}}. |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/updateNodeConfig \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"nodeId": "example",
"config": {}
}'/api/v1/flow/editNodeConfigEdit node config by merging partial updates. Unlike updateNodeConfig which replaces entire config, this merges only the fields you provide.
Parameters
flowId | stringrequired | Flow ID |
nodeId | stringrequired | Node ID within the flow |
config | objectrequired | Partial config to merge. Only provided fields are updated, existing fields are preserved. |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/editNodeConfig \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"nodeId": "example",
"config": {}
}'/api/v1/flow/deletePermanently delete a flow
Parameters
id | stringrequired | Flow ID to delete |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/delete \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"id": "example"
}'/api/v1/flow/createWebhookCreate a webhook trigger for a flow
Parameters
flowId | stringrequired | Flow ID |
triggerId | stringrequired | Trigger node ID in the flow |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/createWebhook \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"triggerId": "example"
}'/api/v1/flow/getWebhookGet webhook details. Params: flowId, triggerId (trigger node ID). Returns the live webhook link: treat it as a password (so this is a write tool that needs an edit role: a read-only connection or a Viewer is refused it).
Parameters
flowId | stringrequired | Flow ID the trigger belongs to |
triggerId | stringrequired | Trigger node ID |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getWebhook \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"triggerId": "example"
}'/api/v1/flow/deleteWebhookDelete a webhook trigger
Parameters
flowId | stringrequired | Flow ID the trigger belongs to |
triggerId | stringrequired | Trigger node ID |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/deleteWebhook \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"triggerId": "example"
}'/api/v1/flow/createScheduleCreate a schedule trigger for a flow
Parameters
flowId | stringrequired | Flow ID |
triggerId | stringrequired | Trigger node ID |
cronExpression | stringrequired | Cron expression (5 parts): minute hour day month weekday. Example: "0 9 * * *" for 9am daily |
timezone | string | Timezone (default: UTC). Example: "America/New_York" |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/createSchedule \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"triggerId": "example",
"cronExpression": "example"
}'/api/v1/flow/getScheduleGet schedule details
Parameters
triggerId | stringrequired | Trigger node ID |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getSchedule \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"triggerId": "example"
}'/api/v1/flow/updateScheduleUpdate a schedule trigger configuration
Parameters
triggerId | stringrequired | Trigger node ID |
cronExpression | stringrequired | Cron expression (5 parts): minute hour day month weekday |
timezone | stringrequired | Timezone. Example: "America/New_York", "UTC" |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/updateSchedule \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"triggerId": "example",
"cronExpression": "example",
"timezone": "example"
}'/api/v1/flow/deleteScheduleDelete a schedule trigger
Parameters
triggerId | stringrequired | Trigger node ID |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/deleteSchedule \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"triggerId": "example"
}'/api/v1/flow/getExecutionsGet execution history for a flow with pagination
Parameters
flowId | stringrequired | Flow ID |
limit | number | Max results (1-50, default 10) |
cursor | string | Pagination cursor from previous response |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getExecutions \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"limit": 0,
"cursor": "example"
}'/api/v1/flow/getExecutionDetailsGet full execution details with node results and flow snapshot
Parameters
executionId | stringrequired | Execution ID from getExecutions |
includeFullData | boolean | Include full node results (for copying data) |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getExecutionDetails \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"executionId": "example",
"includeFullData": true
}'/api/v1/flow/getActiveExecutionGet the most recent running execution for a flow
Parameters
flowId | stringrequired | Flow ID |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getActiveExecution \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example"
}'/api/v1/flow/getActiveExecutionsGet all currently running executions for a flow
Parameters
flowId | stringrequired | Flow ID |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getActiveExecutions \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example"
}'/api/v1/flow/getSnapshotsGet flow version history (snapshots). Each save creates a snapshot for rollback.
Parameters
flowId | stringrequired | Flow ID |
cursor | string | Pagination cursor |
limit | number | Max results (1-50, default 20) |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getSnapshots \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"cursor": "example",
"limit": 0
}'/api/v1/flow/deleteSnapshotDelete a snapshot (cannot delete the latest snapshot)
Parameters
snapshotId | stringrequired | Snapshot ID from getSnapshots |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/deleteSnapshot \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"snapshotId": "example"
}'/api/v1/flow/restoreFromSnapshotByIdRestore flow nodes and edges from a previous snapshot
Parameters
flowId | stringrequired | Flow ID |
snapshotId | stringrequired | Snapshot ID to restore from |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/restoreFromSnapshotById \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"snapshotId": "example"
}'/api/v1/flow/stopExecutionStop a running execution
Parameters
executionId | stringrequired | Execution ID to stop |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/stopExecution \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"executionId": "example"
}'/api/v1/flow/runManualFlowExecute a flow manually with optional trigger data
Parameters
flowId | stringrequired | Flow ID to execute |
triggerData | object | Data to pass to the trigger node |
triggerId | string | Specific trigger node ID (uses manual trigger if not specified) |
executionId | string | Custom execution ID for a NEW run (generated if not provided); an id already in use is refused |
executionMode | string | Execution mode: "test" uses pinned data, "live" runs normally |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/runManualFlow \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"triggerData": {},
"triggerId": "example"
}'/api/v1/flow/pinNodeDataPin data to a node for testing. Pinned nodes use fixed output instead of executing.
Parameters
flowId | stringrequired | Flow ID |
nodeId | stringrequired | Node ID to pin data to |
input | any | Input data to pin |
output | any | Output data to pin - used as fixed output in test mode |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/pinNodeData \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"nodeId": "example",
"input": {}
}'/api/v1/flow/unpinNodeDataRemove pinned data from a node so it executes normally
Parameters
flowId | stringrequired | Flow ID |
nodeId | stringrequired | Node ID to unpin |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/unpinNodeData \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"nodeId": "example"
}'/api/v1/flow/toggleActiveToggle flow active/inactive. Inactive flows do not process webhook or schedule triggers.
Parameters
flowId | stringrequired | Flow ID |
expectActive | boolean | Whether the flow is on now (as you last saw it). If it is no longer in that state, nothing is changed. |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/toggleActive \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"expectActive": true
}'/api/v1/flow/enterListenModeShow the next real runs of this flow live in the editor for a while (webhook or table trigger). The flow still runs as usual; listening only lets the editor watch.
Parameters
flowId | stringrequired | Flow ID |
triggerType | stringrequired | Type of trigger to listen for |
duration | integer | Listen duration in ms (1 second to 15 minutes; default 5 minutes) |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/enterListenMode \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"triggerType": "example",
"duration": {}
}'/api/v1/flow/exitListenModeStop watching this flow's runs in the editor. Listening is shared by everyone in the workspace on this flow, so it stops for all of them.
Parameters
flowId | stringrequired | Flow ID |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/exitListenMode \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example"
}'/api/v1/flow/cancelQueuedFlowCancel a flow that is waiting in the execution queue
Parameters
executionId | stringrequired | Execution ID of the queued flow |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/cancelQueuedFlow \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"executionId": "example"
}'/api/v1/flow/getHelpGet help for Flows API. Call with topic to get focused guidance.
Parameters
topic | string | Topic: "overview", "nodes", "triggers", "execution", "testing" |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getHelp \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"topic": "example"
}'/api/v1/flow/getAccessRulesGet the execute access rules for a flow (who may invoke it from a published app via flows.invoke), and hasHome (true when the flow already belongs to a site). Its home sites (`sites`) list only the sites you may open; saving the list keeps any you can't see. Param: id (flow ID).
Parameters
id | stringrequired | Flow ID from list |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getAccessRules \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"id": "example"
}'/api/v1/flow/setAccessRulesSet who may invoke a flow from published apps via flows.invoke(). Flows are DENY-BY-DEFAULT — without rules only the owner can invoke. A flow a page starts runs as the workspace (it can read any of the owner's bases): only what its response node returns reaches the visitor. Params: id (flow ID), accessRules ({ execute: Condition, sites?: [siteId] } — same shape as backend-function rules). sites = the flow's HOME sites: only their members count for signed-in / role / plan / property rules, and through any other site the flow runs only if its rule says "Anyone, everywhere". Public has two levels: { type: "public", scope: "home" } = "Anyone on this site" (only through its home sites) and { type: "public", scope: "everywhere" } = "Anyone, everywhere". A public rule with no level keeps the saved one; made public now on a flow with home sites it starts as "Anyone on this site"; a flow with NO sites made public must name its sites or say scope "everywhere" — refused otherwise. Saving is checked like any flow save: you may only save rules you may change (refused if the flow holds something the person you act for may not use). Leaving `sites` out keeps the saved list.
Parameters
id | stringrequired | Flow ID from list |
accessRules | objectrequired | { execute: Condition, sites?: [siteId] } — same shape as backend-function rules (public/authenticated/has_role/user_property/policy refs, or {all|any|not} groups). `sites` = the flow's home sites: only their members count for signed-in/role/plan/property rules, and only they can run it unless it is "Anyone, everywhere" (left out = keep the saved list). A public leaf has two levels: { type: "public", scope: "home" } = "Anyone on this site" (through its home sites only — what a newly public flow with home sites starts as; a flow with no sites made public must name them or say "everywhere") and { type: "public", scope: "everywhere" } = "Anyone, everywhere" (through any of your sites). Saving is checked like any flow save: you may only save rules you may change. Missing/empty execute = nobody can invoke from the published app (the owner always can). Example public form flow on one site: { execute: [{ type: "public", scope: "home" }], sites: ["<siteId>"] }. |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/setAccessRules \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"id": "example",
"accessRules": {}
}'/api/v1/flow/getWhoCanRun"Who can run this flow": everyone in the workspace (no list), or the roles, people and agents its builder chose (the Owner and Admins always can). Also what anyone who can run it can use it to do.
Parameters
flowId | stringrequired | Flow ID from list |
withChangeRefusal | boolean | Also say whether you may change the list, and why not (the whole save check: ask it only when about to change it). |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/getWhoCanRun \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"withChangeRefusal": true
}'/api/v1/flow/setWhoCanRunSet "Who can run this flow". The Owner and Admins can always run it; the flow's own triggers always start it.
Parameters
flowId | stringrequired | Flow ID from list |
everyone | booleanrequired | true: everyone in the workspace can run it (the lists are ignored) |
roles | arrayrequired | Roles that can run it: admin, editor (Developer), viewer |
people | arrayrequired | Member user ids that can run it |
agents | arrayrequired | Agent ids that can run it |
Example Request
curl -X POST https://app.serenitiesai.com/api/v1/flow/setWhoCanRun \
-H "Authorization: Bearer mk_live_your_api_key" \
-H "Content-Type: application/json" \
-d '{
"flowId": "example",
"everyone": true,
"roles": {}
}'