Management API
Define agents and skills, publish them, and read the project's usage.
Alongside conversations, the platform stores agent definitions (a system prompt, a model profile, and which tools, sub-agents and skills the agent may use) and skills (reusable instructions an agent can load). These calls go through AICE's shared transport, so they raise the AICE errors and retry like every other service.
Agents
agent = client.agents.create({
"name": "Support triage",
"description": "Sorts incoming tickets and drafts first replies.",
"system_prompt": "You triage support tickets for Acme…",
"model_profile": "openweights:glm-5.3-flash",
"tool_bindings": ["knowledge"],
"subagent_bindings": [],
"skill_bindings": [],
})
client.agents.publish(agent["id"])
agents = client.agents.list()["agents"]A new definition is a draft until it's published; only a preview run can run a draft. The platform assigns id, the project, version and status itself, and ignores them if you send them. Any other unknown field is refused with a 422, as is a definition that wouldn't do what it says: a model with no key on the platform, a tool server that doesn't exist, or a subagent or skill id that isn't in the project.
| Field | What it does |
|---|---|
name, description | Other agents read these to decide whether to hand this one work. |
system_prompt | The agent's instructions. |
model_profile | "provider:model" from client.models.list(), or null/"default" for the platform's default. A run's own provider/model still win. |
tool_bindings | Tool server names from client.tools.list(): knowledge, crawler, data_brain. null means every server, [] means none. |
subagent_bindings | Ids of your agents this one may hand work to, with its task tool. A subagent can delegate on to its own, up to the platform's depth limit (2 by default), at most 5 times a run. |
skill_bindings | Ids of your skills this one may load with load_skill. |
subagent_discovery, skill_discovery | Also let it find any of your published agents or skills, not just the bound ones. |
Change an agent in place with agents.update(id, changes): the id stays, so code that runs it by id picks up the change, and version goes up. agents.delete(id) fails with a 409 while another agent binds it, naming them in details.used_by; pass force to remove those bindings and delete it anyway.
To draw agents, tools and skills as a flowchart, test them and export this JSON, use the console's Agent Studio.
Skills
skill = client.skills.create({
"name": "refund-policy",
"description": "How to decide whether a refund is allowed.",
"content": "Refunds are allowed within 30 days when…",
})
client.skills.publish(skill["id"])
skills = client.skills.list()["skills"]Usage
usage = client.usage.get()Returns the project's usage counters.
Suggestions
suggestions.create_for_thread and suggestions.starters belong to conversations. See Titles and follow-ups.
Reference
| Python | TypeScript | Endpoint | Returns |
|---|---|---|---|
agents.list(status=) | agents.list({ status }) | GET /agents | {"agents": [...]} |
agents.get(id) | agents.get(id) | GET /agents/{id} | the agent, draft or published |
agents.create(spec) | agents.create(spec) | POST /agents | the new draft |
agents.update(id, changes) | agents.update(id, changes) | PATCH /agents/{id} | the agent, version + 1 |
agents.delete(id, force=) | agents.delete(id, { force }) | DELETE /agents/{id} | nothing; 409 while bound |
agents.publish(id) | agents.publish(id) | POST /agents/{id}/publish | the published agent |
agents.import_bundle(board) | agents.importBundle(board) | several | {entry_agent_id, ids} |
skills.list(), get, create, update, delete, publish | the same | /skills… | as for agents |
tools.list() | tools.list() | GET /tools | {"servers": [{name, status, tools}]} |
models.list() | models.list() | GET /models | {default, providers, limits} |
usage.get() | usage.get() | GET /usage | usage counters |
suggestions.starters() | suggestions.starters() | GET /suggestions/starters | {items, generated_at, source, generated} |
suggestions.create_for_thread(id) | suggestions.createForThread(id) | POST /threads/{id}/postturn | {thread_name, suggestions, generated} |
These need SDK 0.3.0 or later. Two query parameters still can't be passed through the client: window on usage and retitle on title generation.