Agents
Manage agents over the API — create and edit them, move a draft through its version lifecycle, attach data and tools, and export or import an agent as a package. To talk to an agent, see Conversations.
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 | Current version label. |
| live_version_id | string | ID of the published live version, if any. |
| 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 (requires ownership). Returns 204 No Content.
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. 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
Attaching or detaching requires ownership of the agent — attaching to an agent you don't own returns 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.
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.
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.
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.
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 matching and the PublicImportedAgent response follow the same behavior as creating from an import.
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 does not own the agent. |
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. |
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 not the owner, 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 to attach, unresolved MCP servers, and files to add. - Create any unresolved MCP servers 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.