English
Assistant
Routes are relative to <PUBLIC_BASE_URL>; request and response bodies are JSON unless stated otherwise. Authentication, scopes, pagination and the error format are described in the REST API guides.
GET /api/v1/assistant/models
List the models available to the assistant
The default model of the instance and the choices the member may pick from.
Access — Member session or API key with scope assistant:read.
Responses
200 — The models.
| Field | Type | Required |
|---|---|---|
default | object | null | yes |
options | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"default": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" },
"source": {
"type": "string",
"enum": [ "purpose", "instanceDefault", "configurationOrder" ]
}
},
"required": [ "provider", "model", "source" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"options": {
"type": "array",
"items": {
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string" },
"connectionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"connectionLabel": { "type": "string" },
"supportsTools": { "type": "boolean" }
},
"required": [
"provider",
"model",
"connectionId",
"connectionLabel",
"supportsTools"
],
"additionalProperties": false
}
}
},
"required": [ "default", "options" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
GET /api/v1/assistant/conversations
List my conversations
The most recent conversations of the member, optionally those attached to one workflow.
Access — Member session or API key with scope assistant:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
workflowId | query | string | no |
limit | query | integer | no |
Responses
200 — The conversations.
| Field | Type | Required |
|---|---|---|
conversations | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"conversations": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"title": { "type": "string" },
"workflowId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"model": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string", "minLength": 1, "maxLength": 200 },
"connectionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"lastModel": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"status": {
"type": "string",
"enum": [ "idle", "running", "failed", "cancelled" ]
},
"usage": {
"type": "object",
"properties": {
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"inputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"outputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"costUsd": {
"anyOf": [ { "type": "number", "minimum": 0 }, { "type": "null" } ]
}
},
"required": [ "calls", "inputTokens", "outputTokens", "costUsd" ],
"additionalProperties": false
},
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [
"id",
"title",
"workflowId",
"model",
"lastModel",
"status",
"usage",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
}
},
"required": [ "conversations" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — assistant.bad_request. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/assistant/conversations
Open a conversation
Creates an empty conversation, optionally attached to a workflow and with a chosen model. A model outside the allowed choices is assistant.model_not_allowed.
Access — Member session or API key with scope assistant:write.
Request body (application/json)
| Field | Type | Required |
|---|---|---|
workflowId | string | no |
title | string | no |
model | object | no |
JSON Schema
json
{
"type": "object",
"properties": {
"workflowId": { "type": "string", "minLength": 1 },
"title": { "type": "string", "minLength": 1, "maxLength": 120 },
"model": {
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string", "minLength": 1, "maxLength": 200 },
"connectionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [ "provider", "model" ]
}
}
}Responses
201 — The conversation.
| Field | Type | Required |
|---|---|---|
conversation | object | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"conversation": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"title": { "type": "string" },
"workflowId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"model": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string", "minLength": 1, "maxLength": 200 },
"connectionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"lastModel": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"status": {
"type": "string",
"enum": [ "idle", "running", "failed", "cancelled" ]
},
"usage": {
"type": "object",
"properties": {
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"inputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"outputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"costUsd": {
"anyOf": [ { "type": "number", "minimum": 0 }, { "type": "null" } ]
}
},
"required": [ "calls", "inputTokens", "outputTokens", "costUsd" ],
"additionalProperties": false
},
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [
"id",
"title",
"workflowId",
"model",
"lastModel",
"status",
"usage",
"createdAt",
"updatedAt"
],
"additionalProperties": false
}
},
"required": [ "conversation" ],
"additionalProperties": false
}400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.
Error codes — assistant.bad_request, assistant.model_not_allowed, assistant.tools_not_supported. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
GET /api/v1/assistant/conversations/{id}
Read a conversation
The conversation, its messages and its proposals. Everything a streamed turn produced is persisted, so this is how a cut connection catches up. A conversation of another member is a 404.
Access — Member session or API key with scope assistant:read.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The conversation.
| Field | Type | Required |
|---|---|---|
conversation | object | yes |
messages | object[] | yes |
proposals | object[] | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"conversation": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"title": { "type": "string" },
"workflowId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"model": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string", "minLength": 1, "maxLength": 200 },
"connectionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [ "provider", "model" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"lastModel": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"status": {
"type": "string",
"enum": [ "idle", "running", "failed", "cancelled" ]
},
"usage": {
"type": "object",
"properties": {
"calls": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"inputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"outputTokens": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"costUsd": {
"anyOf": [ { "type": "number", "minimum": 0 }, { "type": "null" } ]
}
},
"required": [ "calls", "inputTokens", "outputTokens", "costUsd" ],
"additionalProperties": false
},
"createdAt": { "type": "string" },
"updatedAt": { "type": "string" }
},
"required": [
"id",
"title",
"workflowId",
"model",
"lastModel",
"status",
"usage",
"createdAt",
"updatedAt"
],
"additionalProperties": false
},
"messages": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"role": { "type": "string", "enum": [ "user", "assistant", "tool" ] },
"content": { "type": "string" },
"toolCalls": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string" },
"name": { "type": "string" },
"arguments": {}
},
"required": [ "id", "name", "arguments" ],
"additionalProperties": false
}
},
"toolCallId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"toolName": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"toolOk": { "anyOf": [ { "type": "boolean" }, { "type": "null" } ] },
"toolResult": { "anyOf": [ {}, { "type": "null" } ] },
"model": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" }
},
"required": [
"id",
"role",
"content",
"toolCalls",
"toolCallId",
"toolName",
"toolOk",
"toolResult",
"model",
"createdAt"
],
"additionalProperties": false
}
},
"proposals": {
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"conversationId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"kind": { "type": "string", "enum": [ "create_draft", "update_draft" ] },
"status": {
"type": "string",
"enum": [
"proposed",
"accepting",
"accepted",
"rejected",
"stale",
"failed"
]
},
"summary": { "type": "string" },
"name": { "type": "string" },
"workflowId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseVersionId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"graph": {
"type": "object",
"properties": {
"id": {},
"workflowId": {},
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {},
"type": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
"delayMs": {
"type": "integer",
"minimum": 1000,
"maximum": 3600000
}
},
"required": [ "maxAttempts" ],
"additionalProperties": false
},
"timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [ "id", "type", "version", "name", "params", "onError" ],
"additionalProperties": false
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {},
"output": { "type": "string" },
"to": {},
"input": { "type": "string" },
"kind": { "type": "string", "enum": [ "data", "service" ] }
},
"required": [ "from", "output", "to" ],
"additionalProperties": false
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 64 },
"text": { "default": "", "type": "string", "maxLength": 4000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": { "type": "number", "minimum": 120, "maximum": 2000 },
"height": { "type": "number", "minimum": 80, "maximum": 2000 }
},
"required": [ "width", "height" ],
"additionalProperties": false
},
"color": {
"default": "jaune",
"type": "string",
"enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
}
},
"required": [ "id", "text", "position", "size", "color" ],
"additionalProperties": false
}
},
"pins": {
"type": "object",
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
},
"required": [ "output", "pinnedAt" ],
"additionalProperties": false
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
},
"validation": {
"type": "object",
"properties": {
"ok": { "type": "boolean" },
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "code", "message", "nodeId" ],
"additionalProperties": false
}
},
"warnings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "code", "message", "nodeId" ],
"additionalProperties": false
}
}
},
"required": [ "ok", "errors", "warnings" ],
"additionalProperties": false
},
"diff": {
"anyOf": [
{
"type": "object",
"properties": {
"addedNodes": { "type": "array", "items": { "type": "string" } },
"removedNodes": { "type": "array", "items": { "type": "string" } },
"changedNodes": { "type": "array", "items": { "type": "string" } },
"addedConnections": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"removedConnections": {
"type": "integer",
"minimum": 0,
"maximum": 9007199254740991
},
"renamed": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"addedNodes",
"removedNodes",
"changedNodes",
"addedConnections",
"removedConnections",
"renamed"
],
"additionalProperties": false
},
{ "type": "null" }
]
},
"tables": {
"type": "array",
"items": {
"type": "object",
"properties": {
"slug": { "type": "string", "minLength": 1, "maxLength": 60 },
"name": { "type": "string", "minLength": 1, "maxLength": 120 },
"columns": {
"minItems": 1,
"maxItems": 20,
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 60,
"description": "Machine key: lowercase, a-z0-9_."
},
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
"type": {
"type": "string",
"enum": [
"text",
"number",
"boolean",
"date",
"datetime",
"select",
"email"
]
},
"isKey": {
"type": "boolean",
"description": "Part of the row key used to find/update a row."
}
},
"required": [ "key", "label", "type", "isKey" ],
"additionalProperties": false
}
}
},
"required": [ "slug", "name", "columns" ],
"additionalProperties": false
}
},
"prerequisites": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "table" },
"ref": { "type": "string" },
"slug": { "type": "string" },
"name": { "type": "string" },
"columns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 60,
"description": "Machine key: lowercase, a-z0-9_."
},
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
"type": {
"type": "string",
"enum": [
"text",
"number",
"boolean",
"date",
"datetime",
"select",
"email"
]
},
"isKey": {
"type": "boolean",
"description": "Part of the row key used to find/update a row."
}
},
"required": [ "key", "label", "type", "isKey" ],
"additionalProperties": false
}
}
},
"required": [ "kind", "ref", "slug", "name", "columns" ],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "connection" },
"connection": { "type": "string" },
"credentialType": { "type": "string" },
"capability": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"nodeId": { "type": "string" },
"nodeType": { "type": "string" }
},
"required": [
"kind",
"connection",
"credentialType",
"capability",
"nodeId",
"nodeType"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "complete" },
"nodeId": { "type": "string" },
"nodeType": { "type": "string" },
"param": { "type": "string" },
"label": {
"type": "object",
"properties": { "fr": { "type": "string" }, "en": { "type": "string" } },
"required": [ "fr", "en" ],
"additionalProperties": false
}
},
"required": [ "kind", "nodeId", "nodeType", "param", "label" ],
"additionalProperties": false
}
]
}
},
"result": {
"anyOf": [
{
"type": "object",
"properties": {
"workflowId": { "type": "string" },
"versionId": { "type": "string" },
"createdTables": { "type": "array", "items": { "type": "string" } }
},
"required": [ "workflowId", "versionId", "createdTables" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"failureCode": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"decidedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"id",
"conversationId",
"kind",
"status",
"summary",
"name",
"workflowId",
"baseVersionId",
"graph",
"validation",
"diff",
"tables",
"prerequisites",
"result",
"failureCode",
"createdAt",
"decidedAt"
],
"additionalProperties": false
}
}
},
"required": [ "conversation", "messages", "proposals" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — assistant.conversation_not_found. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
PATCH /api/v1/assistant/conversations/{id}
Rename a conversation or change its model
Access — Member session or API key with scope assistant:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
title | string | no |
model | object | null | no |
JSON Schema
json
{
"type": "object",
"properties": {
"title": { "type": "string", "minLength": 1, "maxLength": 120 },
"model": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string", "minLength": 1, "maxLength": 200 },
"connectionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [ "provider", "model" ]
},
{ "type": "null" }
]
}
}
}Responses
200 — The conversation, updated.
| Field | Type | Required |
|---|---|---|
conversation | object | yes |
Same schema as POST /api/v1/assistant/conversations.
400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — assistant.bad_request, assistant.conversation_not_found, assistant.model_not_allowed, assistant.tools_not_supported. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
DELETE /api/v1/assistant/conversations/{id}
Delete a conversation
Access — Member session or API key with scope assistant:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
204 — Deleted.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — assistant.conversation_not_found. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/assistant/conversations/{id}/messages
Send a message and run a turn
One turn of the assistant: it reads the message, may call tools, and may leave a proposal to accept or reject. Two responses for one request. With Accept: text/event-stream, a 200 is sent at once and the turn streams as server-sent events (event: is the event type, data: the JSON event), ending with assistant.turn_done carrying the full turn, or assistant.error carrying the error code: refusals such as 409 assistant.busy arrive INSIDE the stream. Otherwise the JSON of the complete turn is returned, or the error with its status. Closing the connection does not stop the turn: use cancel.
Access — Member session or API key with scope assistant:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Request body (application/json)
| Field | Type | Required |
|---|---|---|
content | string | yes |
model | object | null | no |
JSON Schema
json
{
"type": "object",
"properties": {
"content": { "type": "string", "minLength": 1, "maxLength": 12000 },
"model": {
"anyOf": [
{
"type": "object",
"properties": {
"provider": {
"type": "string",
"enum": [
"anthropic",
"openai",
"mistral",
"openrouter",
"ollama",
"openai_compatible"
]
},
"model": { "type": "string", "minLength": 1, "maxLength": 200 },
"connectionId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
}
},
"required": [ "provider", "model" ]
},
{ "type": "null" }
]
}
},
"required": [ "content" ]
}Responses
200 — The stream of events (text/event-stream). Without the Accept header, the body is instead the JSON of the complete turn (AssistantTurnResponse, the same object assistant.turn_done carries).
Content type : text/event-stream
400 — The request does not match its schema.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
This operation accepts an Idempotency-Key header: replaying the same request with the same key returns the original response instead of acting twice. See Idempotency.
Error codes — assistant.bad_request, assistant.conversation_not_found, assistant.busy, assistant.model_not_allowed, assistant.tools_not_supported, assistant.budget_exceeded, assistant.cancelled. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/assistant/conversations/{id}/cancel
Interrupt the running turn
cancelled: false when no turn was running. The streamed turn then ends with assistant.error and the code assistant.cancelled.
Access — Member session or API key with scope assistant:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — Whether a turn was interrupted.
| Field | Type | Required |
|---|---|---|
cancelled | boolean | yes |
JSON Schema
json
{
"type": "object",
"properties": { "cancelled": { "type": "boolean" } },
"required": [ "cancelled" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — assistant.conversation_not_found. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/assistant/proposals/{id}/accept
Accept a proposal
Applies the proposal: creates the draft, or updates the attached one. 409 assistant.proposal_decided when already accepted or rejected; 409 assistant.proposal_stale when the draft changed since the proposal was made.
Access — Member session or API key with scope assistant:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The proposal, accepted.
| Field | Type | Required |
|---|---|---|
proposal | object | yes |
JSON Schema
json
{
"type": "object",
"properties": {
"proposal": {
"type": "object",
"properties": {
"id": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"conversationId": {
"type": "string",
"format": "uuid",
"pattern": "^([0-9a-fA-F]{8}-[0-9a-fA-F]{4}-[1-8][0-9a-fA-F]{3}-[89abAB][0-9a-fA-F]{3}-[0-9a-fA-F]{12}|00000000-0000-0000-0000-000000000000|ffffffff-ffff-ffff-ffff-ffffffffffff)$"
},
"kind": { "type": "string", "enum": [ "create_draft", "update_draft" ] },
"status": {
"type": "string",
"enum": [ "proposed", "accepting", "accepted", "rejected", "stale", "failed" ]
},
"summary": { "type": "string" },
"name": { "type": "string" },
"workflowId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"baseVersionId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"graph": {
"type": "object",
"properties": {
"id": {},
"workflowId": {},
"nodes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": {},
"type": { "type": "string", "minLength": 1, "maxLength": 128 },
"version": {
"type": "integer",
"exclusiveMinimum": 0,
"maximum": 9007199254740991
},
"name": { "type": "string", "minLength": 1, "maxLength": 200 },
"params": {
"default": {},
"type": "object",
"propertyNames": { "type": "string" },
"additionalProperties": {}
},
"onError": {
"default": "fail",
"type": "string",
"enum": [ "fail", "continue", "errorPort" ]
},
"retry": {
"type": "object",
"properties": {
"maxAttempts": { "type": "integer", "minimum": 1, "maximum": 10 },
"delayMs": { "type": "integer", "minimum": 1000, "maximum": 3600000 }
},
"required": [ "maxAttempts" ],
"additionalProperties": false
},
"timeoutMs": { "type": "integer", "minimum": 5000, "maximum": 1800000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"disabled": { "type": "boolean" },
"notes": { "type": "string", "maxLength": 2000 }
},
"required": [ "id", "type", "version", "name", "params", "onError" ],
"additionalProperties": false
}
},
"connections": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"from": {},
"output": { "type": "string" },
"to": {},
"input": { "type": "string" },
"kind": { "type": "string", "enum": [ "data", "service" ] }
},
"required": [ "from", "output", "to" ],
"additionalProperties": false
}
},
"notes": {
"readOnly": true,
"type": "array",
"items": {
"type": "object",
"properties": {
"id": { "type": "string", "minLength": 1, "maxLength": 64 },
"text": { "default": "", "type": "string", "maxLength": 4000 },
"position": {
"type": "object",
"properties": { "x": { "type": "number" }, "y": { "type": "number" } },
"required": [ "x", "y" ],
"additionalProperties": false
},
"size": {
"default": { "width": 240, "height": 160 },
"type": "object",
"properties": {
"width": { "type": "number", "minimum": 120, "maximum": 2000 },
"height": { "type": "number", "minimum": 80, "maximum": 2000 }
},
"required": [ "width", "height" ],
"additionalProperties": false
},
"color": {
"default": "jaune",
"type": "string",
"enum": [ "jaune", "menthe", "ciel", "rose", "lavande" ]
}
},
"required": [ "id", "text", "position", "size", "color" ],
"additionalProperties": false
}
},
"pins": {
"type": "object",
"propertyNames": { "type": "string", "minLength": 1, "maxLength": 64 },
"additionalProperties": {
"type": "object",
"properties": {
"output": {},
"port": { "type": "string" },
"pinnedAt": { "type": "string", "minLength": 1, "maxLength": 64 }
},
"required": [ "output", "pinnedAt" ],
"additionalProperties": false
}
}
},
"required": [ "id", "workflowId", "nodes", "connections" ],
"additionalProperties": false
},
"validation": {
"type": "object",
"properties": {
"ok": { "type": "boolean" },
"errors": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "code", "message", "nodeId" ],
"additionalProperties": false
}
},
"warnings": {
"type": "array",
"items": {
"type": "object",
"properties": {
"code": { "type": "string" },
"message": { "type": "string" },
"nodeId": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [ "code", "message", "nodeId" ],
"additionalProperties": false
}
}
},
"required": [ "ok", "errors", "warnings" ],
"additionalProperties": false
},
"diff": {
"anyOf": [
{
"type": "object",
"properties": {
"addedNodes": { "type": "array", "items": { "type": "string" } },
"removedNodes": { "type": "array", "items": { "type": "string" } },
"changedNodes": { "type": "array", "items": { "type": "string" } },
"addedConnections": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"removedConnections": { "type": "integer", "minimum": 0, "maximum": 9007199254740991 },
"renamed": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"addedNodes",
"removedNodes",
"changedNodes",
"addedConnections",
"removedConnections",
"renamed"
],
"additionalProperties": false
},
{ "type": "null" }
]
},
"tables": {
"type": "array",
"items": {
"type": "object",
"properties": {
"slug": { "type": "string", "minLength": 1, "maxLength": 60 },
"name": { "type": "string", "minLength": 1, "maxLength": 120 },
"columns": {
"minItems": 1,
"maxItems": 20,
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 60,
"description": "Machine key: lowercase, a-z0-9_."
},
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
"type": {
"type": "string",
"enum": [
"text",
"number",
"boolean",
"date",
"datetime",
"select",
"email"
]
},
"isKey": {
"type": "boolean",
"description": "Part of the row key used to find/update a row."
}
},
"required": [ "key", "label", "type", "isKey" ],
"additionalProperties": false
}
}
},
"required": [ "slug", "name", "columns" ],
"additionalProperties": false
}
},
"prerequisites": {
"type": "array",
"items": {
"oneOf": [
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "table" },
"ref": { "type": "string" },
"slug": { "type": "string" },
"name": { "type": "string" },
"columns": {
"type": "array",
"items": {
"type": "object",
"properties": {
"key": {
"type": "string",
"minLength": 1,
"maxLength": 60,
"description": "Machine key: lowercase, a-z0-9_."
},
"label": { "type": "string", "minLength": 1, "maxLength": 120 },
"type": {
"type": "string",
"enum": [
"text",
"number",
"boolean",
"date",
"datetime",
"select",
"email"
]
},
"isKey": {
"type": "boolean",
"description": "Part of the row key used to find/update a row."
}
},
"required": [ "key", "label", "type", "isKey" ],
"additionalProperties": false
}
}
},
"required": [ "kind", "ref", "slug", "name", "columns" ],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "connection" },
"connection": { "type": "string" },
"credentialType": { "type": "string" },
"capability": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"nodeId": { "type": "string" },
"nodeType": { "type": "string" }
},
"required": [
"kind",
"connection",
"credentialType",
"capability",
"nodeId",
"nodeType"
],
"additionalProperties": false
},
{
"type": "object",
"properties": {
"kind": { "type": "string", "const": "complete" },
"nodeId": { "type": "string" },
"nodeType": { "type": "string" },
"param": { "type": "string" },
"label": {
"type": "object",
"properties": { "fr": { "type": "string" }, "en": { "type": "string" } },
"required": [ "fr", "en" ],
"additionalProperties": false
}
},
"required": [ "kind", "nodeId", "nodeType", "param", "label" ],
"additionalProperties": false
}
]
}
},
"result": {
"anyOf": [
{
"type": "object",
"properties": {
"workflowId": { "type": "string" },
"versionId": { "type": "string" },
"createdTables": { "type": "array", "items": { "type": "string" } }
},
"required": [ "workflowId", "versionId", "createdTables" ],
"additionalProperties": false
},
{ "type": "null" }
]
},
"failureCode": { "anyOf": [ { "type": "string" }, { "type": "null" } ] },
"createdAt": { "type": "string" },
"decidedAt": { "anyOf": [ { "type": "string" }, { "type": "null" } ] }
},
"required": [
"id",
"conversationId",
"kind",
"status",
"summary",
"name",
"workflowId",
"baseVersionId",
"graph",
"validation",
"diff",
"tables",
"prerequisites",
"result",
"failureCode",
"createdAt",
"decidedAt"
],
"additionalProperties": false
}
},
"required": [ "proposal" ],
"additionalProperties": false
}401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — assistant.proposal_not_found, assistant.proposal_decided, assistant.proposal_stale. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.
POST /api/v1/assistant/proposals/{id}/reject
Reject a proposal
Nothing is applied. 409 assistant.proposal_decided when already accepted or rejected.
Access — Member session or API key with scope assistant:write.
Parameters
| Name | In | Type | Required |
|---|---|---|---|
id | path | string | yes |
Responses
200 — The proposal, rejected.
| Field | Type | Required |
|---|---|---|
proposal | object | yes |
Same schema as POST /api/v1/assistant/proposals/{id}/accept.
401 — No valid session or API key (auth.unauthenticated).
403 — Refused: insufficient role (auth.forbidden), missing scope (api_key.scope_missing, details.required names it) or a route closed to API keys (api_key.session_required).
429 — The API key exceeded its rate limit (api_key.rate_limited); Retry-After says when to retry.
Error codes — assistant.proposal_not_found, assistant.proposal_decided. The common codes (request.bad_request, auth.unauthenticated, api_key.scope_missing, api_key.rate_limited…) apply to every route; see Errors.