Version 2.5
Agents

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.

FieldTypeDescription
idstringAgent ID.
namestringAgent name.
descriptionstringWhat the agent does.
modestringconversational or worker — see agent types.
runbook_textstringRaw text of the agent's runbook.
statestringLifecycle state — draft or live (lowercase).
versionstringCurrent version label.
live_version_idstringID of the published live version, if any.
architecture_namestringThe agent's architecture.
architecture_versionstringArchitecture version.
created_bystringUser who created the agent.
created_at / updated_atstringTimestamps.

List agents

GET /agents

ParameterInTypeRequiredDescription
namequerystringNoFilter 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

FieldTypeRequiredDescription
namestringYesAgent name.
descriptionstringNoWhat the agent does.
runbook_textstringNoThe agent's runbook, as Markdown text.
architecture_namestringNoArchitecture to use (defaults applied).
architecture_versionstringNoArchitecture 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

FieldTypeRequiredDescription
namestringNoNew name.
descriptionstringNoNew description.
runbook_textstringNoNew 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

FieldTypeRequiredDescription
descriptionstringNoChange description for this publish.
connection_mappingsobject<string>NoMap test data-connection IDs → prod data-connection IDs.
mcp_server_mappingsobject<string>NoMap 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 }
FieldTypeDescription
statestringdraft or live (lowercase).
live_version_idstringID of the published live version, if any.
has_draftbooleanWhether 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.

FieldTypeDescription
has_live_versionbooleanWhether the agent has a published live version.
data_connection_optionsarrayOne 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_optionsarrayOne 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": "..." }. Returns 204.
  • 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": "..." }. Returns 204.
  • 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:

StatusWhen
404The agent does not exist or is not visible to the caller.
403The caller does not own the agent.
422The 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:

FieldDescription
is_syncedtrue when the import would make no changes. Unresolved MCP servers do not make it false, because import cannot create or otherwise act on them.
changesField-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_attachExisting workspace MCP servers, represented by name and url, that match the package and would be newly attached.
unresolved_mcp_serversPackage MCP servers, represented by name and url, that have no workspace match and cannot be recreated because packages contain no secrets.
files_to_addShared 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:

  1. Export the current agent with GET /agents/{agent_id}/export and commit the zip to your repository.
  2. Before applying a package, call POST /agents/{agent_id}/diff to inspect the changes, MCP servers to attach, unresolved MCP servers, and files to add.
  3. Create any unresolved MCP servers in the target workspace.
  4. Apply the package with PUT /agents/{agent_id}/import.
  5. Publish the resulting draft when you want the changes to become live.