Stan
Stan is the platform's assistant: it builds workflows, apps and agents, and operates the platform conversationally. The endpoints on this page manage your Stan sessions (each its own conversation, run against a model you choose), the messages sent in them, the runs those messages start, and undoing what a session built. Your current conversation, settings and past conversations are on Stan Settings.
A session is yours alone; nobody else can read or drive it. You may have several sessions and
drive them at the same time. One of them is your current session: the one
POST /stan/messages uses when no session is named.
All endpoints require authentication via the X-API-Key header and the stan:execute scope.
Session Object
{
"_id": "a8Kd2mQx7PzL4nTr",
"mode": "workflows",
"modelId": "6812f0c4a1b2c3d4e5f60718",
"modelName": "Claude Opus",
"activeWorkflowId": "wf_def001",
"activeWorkflowName": "Customer Onboarding",
"messageCount": 7,
"workflowId": "wf_def001",
"current": false
}
| Field | Type | Description |
|---|---|---|
_id | string | The session's id |
mode | string | workflows (building workflows), develop (building apps) or general |
modelId, modelName | string | The model the session runs on |
activeWorkflowId, activeWorkflowName | string | null | The workflow the session opened against |
messageCount | number | Messages in the conversation |
workflowId | string | null | The workflow the session is building |
current | boolean | Whether it is your current session |
POST /api/v1/stan/sessions
Start a session. Your other sessions keep running.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
modelId | string | Yes | A chat model you may use (its _id from AI Models) |
mode | string | No | workflows (default), develop or general |
activeWorkflowId | string | No | The workflow to open against |
activeWorkflowName | string | No | Its name |
Response 201 Created: the session. A model you may not use, or no model
with that id, is 404 not-found.
GET /api/v1/stan/sessions
Your sessions, most recently active first.
| Parameter | Type | Required | Description |
|---|---|---|---|
limit | integer | No | Results per page |
cursor | string | No | meta.nextCursor of the previous page |
Response 200 OK: a page of sessions, each with _id, mode, modelName, messageCount,
lastActivityAt, current and title (the start of its first message).
GET /api/v1/stan/sessions/:id
One of your sessions. Reading it does not make it current.
Response 200 OK: the session.
DELETE /api/v1/stan/sessions/:id
Delete one of your sessions and its conversation. Your other sessions, the current one included, are not touched.
Response 204 No Content
POST /api/v1/stan/sessions/:id/messages
Send a message in a session. Stan answers in the session's own mode. Messages sent while the session is busy wait their turn.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
message | string | Yes | The message |
attachments | array | No | Images (PNG, JPEG, GIF, WebP) and PDF documents sent with the message, each { "name", "mimeType", "data" } with the file's bytes base64 encoded. Each reaches the session's model the way the model declares it can take it: an image to a model that reads images, a PDF as the document itself to a model that reads PDFs and as its text to one that does not. They stay in the conversation: later messages still show them to the model |
async | boolean | No | true answers 202 with the run's id at once instead of waiting for the reply (use it for long builds); poll GET /stan/runs/:id for the result |
Response: the run that answers the message, as GET /stan/runs/:id answers it: 200 OK once it has finished, 202 Accepted while it is still working (with "async": true the message never waits).
{
"data": {
"runId": "run_abc123",
"async": false,
"runStatus": "completed",
"response": "I've added a webhook trigger node to your workflow.",
"resources": { "workflowId": "wf_def001" },
"tokensUsed": 1840,
"toolCalls": [{ "name": "add_workflow_node", "ok": true }]
},
"meta": { "requestId": "req_abc123" }
}
A run still working has an empty response, its live streamingText and streamSeq, and a note naming the run to poll.
| Status | When |
|---|---|
400 validation-error | An attachment the session's model cannot take (an image for a model that does not read images, a scanned PDF for a model that reads documents as text), a file that is not a PNG, JPEG, GIF, WebP or PDF, or no model chosen yet; detail says which and why |
409 cancelled | The message was cancelled before it started |
503 queue-timeout | Earlier messages kept the session busy too long; send it again |
POST /api/v1/stan/sessions/:id/cancel
Stop what is running in a session, and every message still waiting in it.
Response 200 OK: the session.
POST /api/v1/stan/runs/:id/cancel
Stop one run. A running run stops at its next step; a waiting one is cancelled outright.
Response 200 OK: the run, as GET /stan/runs/:id answers it: cancelled when it was
waiting, still running while a running one reaches its next step. A run that has finished, or is
not yours, is 404 not-found.
POST /api/v1/stan/runs/:id/credentials
Give Stan a credential it asked for, without Stan seeing it. When a run pauses to ask for a secret (an API key, a password), the run names the fields it needs; the values sent here are stored straight into the node, data source or MCP server they are for, and the run then continues, told only that the credential is configured.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
values | object | Yes | Each requested field's value, by field key. Fields the run did not ask for are ignored |
Response 200 OK: the run Stan resumed in, as GET /stan/runs/:id answers it (poll it for
Stan's reply). A run that is not waiting for a credential is 404 not-found; if the credential was
stored but Stan could not resume, the error says so and a message to Stan continues.
GET /api/v1/stan/history
The messages of a conversation, oldest first. Reading it does not make the session current.
| Parameter | Type | Required | Description |
|---|---|---|---|
sessionId | string | No | The session (default: your current one) |
limit | integer | No | Only the last this many messages |
Response 200 OK: { "sessionId", "mode", "total", "messages" }, each message with role
(user or assistant), content and timestamp.
GET /api/v1/stan/sessions/:id/checkpoints
The points a session can be rewound to: one before each run, labelled with the message that started it.
Response 200 OK: { "sessionId", "checkpoints", "lastSeq" }, each checkpoint with seq
(the position to rewind to), runId, label and at. A session that is not yours is
404 not-found.
GET /api/v1/stan/sessions/:id/revert-plan
What undoing the session would remove: the resources Stan created in it, and the delete each would take. Nothing changes.
Response 200 OK: { "sessionId", "resources", "revertPlan", "note" }; each revertPlan
entry has resourceType, resourceId, resourceName and revertTool.
POST /api/v1/stan/sessions/:id/revert
Remove the resources you name from those the session created, each through its own delete and as you, so every check a delete makes still applies. Nothing you do not name is removed.
Request Body
| Field | Type | Required | Description |
|---|---|---|---|
resourceIds | string[] | Yes | The resources to remove, from the revert plan |
Response 200 OK: { "ok", "deleted", "failed", "skipped", "note" }: each resource removed,
each that could not be (with the error), and each left (with the reason).
GET /api/v1/stan/tool-executions
The tools Stan called for you, newest first, including those older than the hot retention (read from the archive).
| Parameter | Type | Required | Description |
|---|---|---|---|
runId | string | No | Only this run's |
limit | integer | No | Results per page |
cursor | string | No | meta.nextCursor of the previous page |
Response 200 OK: a page of calls, each with toolName, runId, mode, input,
success, blocked, error, resultSummary, durationMs and createdAt.