POST/api/v1/flows/{flowId}/sessions
Creates or resolves a chat session and returns its streamUrl, without
running anything.
This exists so you can be reading the stream before the first message produces output. Otherwise turn one is the only turn you cannot watch live: every later message can use the stream opened by its predecessor, but the first would have to race container start-up.
The stream belongs to the session, not the turn — streamUrl stays
valid for every message that follows, because the session’s runId does
not change.
Per-session configuration
The same fields the run trigger accepts — mcpServers, mcpMode,
appendSystemPrompt, disallowedTools, env — apply here, scoped to
this session’s container. That is how one flow serves many tenants over
a warm, persistent session: give the session its own MCP server and a
tenant-scoped token, and withhold write tools with disallowedTools.
The lifetime differs from a run. A run consumes its configuration on
first boot; a session keeps it. A session outlives its container — idle
after 5 minutes unattended, 60 with the stream held open, then respawned
by the next message — and a consumed config would bring that container
back with no MCP servers and no disallowedTools, silently dropping both
the tenant scoping and the “cannot call write tools” guarantee
mid-conversation.
Rotate a short-lived credential with
PATCH /flows/{flowId}/sessions/{sessionId}/config.
POST /flows/{id}/sessions → { sessionId, runId, streamUrl }
GET {streamUrl} → open it, leave it open
POST /flows/{id}/chat → { message, sessionId, stream: true }
202; output arrives on the stream
POST /flows/{id}/chat → next turn, same stream
Authentication
Requires a project API key — see Authentication.
Parameters
| Name | In | Type | Required | Description |
|---|---|---|---|---|
flowId | path | string | required | UUID of the flow to trigger. |
Request body
| Field | Type | Required | Description |
|---|---|---|---|
sessionId | string | optional | Resume an existing conversation. Omit to start a new one and receive a generated id. |
mcpServers | object | optional | MCP servers scoped to this run or session. Remote transports only (http, sse); TLS required off localhost. |
mcpMode | string (merge | replace) | optional |
appendSystemPrompt | string | optional | |
disallowedTools | array | optional | |
env | object | optional | |
name | string | optional | |
labels | object | optional | Caller-supplied name/value pairs, stored on the run and handed back unchanged. FlowKoi never interprets them — use them for whatever you need to correlate a run with your own records: a build id, a tenant id, the version of the files you last pushed. Never put a secret in a label. They are returned by the API and visible to anyone who can see the run in the dashboard. For attribution that must stay private, use the X-Ctx-* headers instead. At most 20 labels. Keys are 1–64 characters, start with a letter or digit, and may contain letters, digits, dots, dashes and underscores. Values are up to 256 characters. |
partialMessages | boolean | optional | Stream text as it is written. Deltas arrive as stream_event; see the run trigger for the full shape. |
Responses
| Status | Description |
|---|---|
201 | Session ready. |
404 | Resource not found or not accessible to this project. |
429 | Rate limit, concurrent cap, or monthly quota exceeded. |
Tag: Chat