Agents
Manage agents over the API — create and edit them, move a draft through its version lifecycle, attach data, tools, and LLMs, and export or import an agent as a package. To talk to an agent, see Conversations.
Endpoints that modify an agent require ownership of the agent or the workspace admin role — other callers get 403.
All paths are relative to the base URL and require an Authorization: Bearer YOUR_API_KEY header.
The agent object
PublicAgent is returned by most endpoints here.
| Field | Type | Description |
|---|---|---|
| id | string | Agent ID. |
| name | string | Agent name. |
| description | string | What the agent does. |
| mode | string | conversational or worker — see agent types. |
| runbook_text | string | Raw text of the agent's runbook. |
| state | string | Lifecycle state — draft or live (lowercase). |
| version | string | The agent-spec's declared version string. |
| live_version_id | string | ID of the published live version, if any. |
| live_version | integer | Monotonic version number of the currently published version — distinct from version. null if never published. |
| live_published_at | string | When the live version was published. null if never published. |
| live_published_by | string | ID of the user who published the live version. null if never published. |
| chat_url | string | URL of this agent's chat UI on this deployment. Valid for both conversational and worker agents. |
| architecture_name | string | The agent's architecture. |
| architecture_version | string | Architecture version. |
| created_by | string | User who created the agent. |
| created_at / updated_at | string | Timestamps. |
List agents
GET /agents
| Parameter | In | Type | Required | Description |
|---|---|---|---|---|
| name | query | string | No | Filter by name (starts-with, case-insensitive). |
Returns a PaginatedResponse whose data is a list of agents. The endpoint takes no paging parameters — all visible agents are returned in one page.
Get agent
GET /agents/{agent_id}
Returns a single PublicAgent.
Create agent
POST /agents
Creates a new agent owned by the authenticated key.
Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | Yes | Agent name. |
| description | string | No | What the agent does. |
| runbook_text | string | No | The agent's runbook, as Markdown text. |
| architecture_name | string | No | Architecture to use (defaults applied). |
| architecture_version | string | No | Architecture version. |
mode can't be set through this API — agents created here are always conversational. Create Worker agents in the application.
curl -X POST 'https://{your-deployment-host}/api/v2/agents' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-H 'Content-Type: application/json' \
-d '{
"name": "Invoice Roast",
"description": "Forensic expense analyst.",
"runbook_text": "## Objective\nExtract and check receipts."
}'Returns the created PublicAgent.
Update agent
PATCH /agents/{agent_id}
Partially updates an agent; absent fields are left untouched.
Body
| Field | Type | Required | Description |
|---|---|---|---|
| name | string | No | New name. |
| description | string | No | New description. |
| runbook_text | string | No | New runbook text. |
You can't patch a live agent directly. Enter edit mode first
(POST /agents/{agent_id}/edit), make your changes against the draft, then
publish.
Delete agent
DELETE /agents/{agent_id}
Deletes an agent. Returns 204 No Content, or 422 if the agent is preinstalled and read-only.
Version lifecycle
An agent has a published live version that users see, and a draft you edit — see the Versioning & lifecycle concept. These endpoints drive that flow.
The lifecycle endpoints require the agent lifecycle capability to be enabled on the deployment.
Enter edit mode
POST /agents/{agent_id}/edit
Flips the agent to draft so you can iterate. Idempotent — a draft stays a draft. If the agent has no individual creator (it's tenant-owned), the caller takes ownership of it as a side effect. Returns the PublicAgent.
Publish
POST /agents/{agent_id}/publish
Snapshots the current draft as a new version, flips the agent to live, and points live_version_id at it. Requires draft state.
Body
| Field | Type | Required | Description |
|---|---|---|---|
| description | string | No | Change description for this publish. |
| connection_mappings | object<string> | No | Map test data-connection IDs → prod data-connection IDs. |
| mcp_server_mappings | object<string> | No | Map test MCP server IDs → prod MCP server IDs. |
The mappings let you swap the draft's test resources for production equivalents at publish time. Returns the PublicAgent.
Discard draft
POST /agents/{agent_id}/discard-draft
Reverts the agent's content to the live version. Requires a prior publish (a live_version_id must exist). Takes the same connection_mappings / mcp_server_mappings body as publish. Returns the PublicAgent.
Get lifecycle state
GET /agents/{agent_id}/state
{ "state": "draft", "live_version_id": "string", "has_draft": true }| Field | Type | Description |
|---|---|---|
| state | string | draft or live (lowercase). |
| live_version_id | string | ID of the published live version, if any. |
| has_draft | boolean | Whether an editable draft exists. |
Get connection options
GET /agents/{agent_id}/connection-options
Read-only helper for the mapping bodies above: for each data connection and MCP server the agent uses, returns the draft's resource, the live version's counterpart (if any), and the compatible resources you can map to. Apply mappings through the publish and edit endpoints — this endpoint changes nothing.
| Field | Type | Description |
|---|---|---|
| has_live_version | boolean | Whether the agent has a published live version. |
| data_connection_options | array | One row per data connection: draft_connection, live_connection (null if none), and available_connections — compatible connections to map to. Each connection carries id, name, engine, plus optional description, tags, and timestamps. |
| mcp_server_options | array | One row per MCP server: draft_server, live_server (null if none), and available_servers. Each server carries id, name, transport, and optional url. |
Attached data, tools & LLMs
Attaching or detaching requires ownership of the agent or the workspace admin role — other callers get 403.
MCP servers
GET /agents/{agent_id}/mcp-servers— list the MCP servers attached to the agent (paginated).POST /agents/{agent_id}/mcp-servers— attach one. Body:{ "mcp_server_id": "..." }. Returns204.DELETE /agents/{agent_id}/mcp-servers/{mcp_server_id}— detach one.
Semantic data models
GET /agents/{agent_id}/semantic-data-models— list the SDMs attached to the agent (paginated).POST /agents/{agent_id}/semantic-data-models— attach one. Body:{ "semantic_data_model_id": "..." }. Returns204.DELETE /agents/{agent_id}/semantic-data-models/{semantic_data_model_id}— detach one.
LLMs
Pin an agent to specific LLM configurations instead of the workspace default.
GET /agents/{agent_id}/llms— list the LLM configurations attached to the agent (paginated). An empty list means the agent uses the workspace default LLM.POST /agents/{agent_id}/llms— attach one. Body:{ "llm_id": "..." }. Returns204.DELETE /agents/{agent_id}/llms/{llm_id}— detach one.
Unlike the admin-only LLM endpoints, the list here returns a credential-free PublicAgentLlm — id, name, kind, description, and models only, never the provider configuration.
Export, import & sync
Export
GET /agents/{agent_id}/export
Streams the agent — with its SDMs, MCP servers, action packages, and shared files — as a zip package. The package also carries the identity (name and kind) of any attached LLM configurations, so an import can re-attach the right ones; it never contains MCP secrets or LLM provider credentials.
Create from an import
POST /agents/import
Creates a new agent from a previously exported zip. Send as multipart/form-data with a file field carrying the zip.
curl -X POST 'https://{your-deployment-host}/api/v2/agents/import' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-F 'file=@agent-package.zip'The response is a PublicImportedAgent: the created PublicAgent plus unresolved_mcp_servers and unresolved_llms.
When the package references MCP servers, import matches them to MCP servers that already exist in the workspace by case-insensitive name and URL and attaches every match. Packages do not contain MCP secrets, so import never creates unmatched servers. Instead, unresolved_mcp_servers lists each unmatched server as { "name": "...", "url": "..." }; create those MCP servers separately and attach them if needed.
LLM references work the same way: import matches them to existing LLM configurations by case-insensitive name and kind and attaches every match. Packages carry no provider credentials, and a reference that matches more than one configuration is also left unattached — import never guesses between candidates. Unmatched references are listed in unresolved_llms as { "name": "...", "kind": "..." }.
Update an existing agent from an import
PUT /agents/{agent_id}/import
Updates an existing agent from an exported zip. Send the same multipart request as POST /agents/import:
curl -X PUT 'https://{your-deployment-host}/api/v2/agents/{agent_id}/import' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-F 'file=@agent-package.zip'Use this endpoint to converge an existing agent on the package you keep under version control. POST /agents/import always creates a new agent; PUT updates the agent at the supplied ID.
Re-importing the same package is idempotent: shared files already present with the same name and content are skipped. Files added outside the package, such as through direct upload, are retained, and import never deletes files.
MCP and LLM matching and the PublicImportedAgent response follow the same behavior as creating from an import; existing attachments are never removed.
For a published agent, the import creates or updates its draft; the published version remains live until you publish the draft. The endpoint returns:
| Status | When |
|---|---|
404 | The agent does not exist or is not visible to the caller. |
403 | The caller is neither the agent's owner nor a workspace admin. |
422 | The agent is preinstalled and read-only. |
Preview an import
POST /agents/{agent_id}/diff
Dry-runs PUT /agents/{agent_id}/import without making changes. Send the exported zip as multipart/form-data with a file field:
curl -X POST 'https://{your-deployment-host}/api/v2/agents/{agent_id}/diff' \
-H 'Authorization: Bearer YOUR_API_KEY' \
-F 'file=@agent-package.zip'Returns a PublicAgentDiff:
| Field | Description |
|---|---|
is_synced | true when the import would make no changes. Unresolved MCP servers do not make it false, because import cannot create or otherwise act on them. |
changes | Field-level changes to the agent definition and semantic data models. Each entry has change (add, update, or delete), field_path, deployed_value, and package_value. |
mcp_servers_to_attach | Existing workspace MCP servers, represented by name and url, that match the package and would be newly attached. |
unresolved_mcp_servers | Package MCP servers, represented by name and url, that have no workspace match and cannot be recreated because packages contain no secrets. |
llms_to_attach | Existing workspace LLM configurations, represented by name and kind, that match the package and would be newly attached. |
unresolved_llms | Package LLM references, represented by name and kind, that have no workspace match and cannot be recreated because packages contain no credentials. |
files_to_add | Shared files that import would add. Identical files are omitted; import never deletes files. |
The endpoint has the same guards as PUT /agents/{agent_id}/import: it returns 404 when the agent is missing or not visible, 403 when the caller is neither the owner nor a workspace admin, and 422 when the agent is preinstalled and read-only.
GitOps workflow
To manage an agent package in version control:
- Export the current agent with
GET /agents/{agent_id}/exportand commit the zip to your repository. - Before applying a package, call
POST /agents/{agent_id}/diffto inspect the changes, MCP servers and LLMs to attach, unresolved references, and files to add. - Create any unresolved MCP servers and LLM configurations in the target workspace.
- Apply the package with
PUT /agents/{agent_id}/import. - Publish the resulting draft when you want the changes to become live.