Skip to content

Create an agent

POST /v1/agents

Creates an agent that the key’s owner owns.

The API applies the same checks and defaults as creating an agent in the Context app. You need permission to create agents in the organization, and the key must have no Agent scope (no list of specific agents). If the request fails, no agent is created.

The agent goes in the workspace named by metadata.workspace_id. Without it, the agent goes in your oldest shared (not private) workspace that you can work in, or in no workspace if there is none.

The key must be a personal key with the agents:write capability. For what each capability allows, see Keys.

Body

NameTypeRequiredDefaultDescription
namestringYesThe agent’s name. Must be between 1 and 100 characters after leading and trailing spaces are trimmed.
modelstring | objectYesA model ID your deployment runs, or default for your deployment’s default model. The object form {id} takes only id.
descriptionstring | nullNoThe agent’s purpose.
systemstring | nullNoThe agent’s instructions.
toolsarray<object> | nullNoThe agent’s built-in tools, as at most one agent_toolset_20260401 entry. Leave it out to get the defaults the app gives a new agent: every tool on with Allow, except web_search. Send [] to turn every built-in tool off.
tools[].default_configobjectNoThe setting for each built-in tool that configs doesn’t name, as {enabled, permission_policy}. Defaults to {enabled: true, permission_policy: {type: "always_allow"}}. web_search stays off whatever this says.
tools[].configsarray<object>NoPer-tool settings, each {name, enabled, permission_policy}. name is one of bash, edit, read, write, glob, grep, web_fetch or web_search. permission_policy is {type: "always_allow"} or {type: "always_ask"}.
skillsarray<object> | nullNoThe agent’s skills, each {type, skill_id}. Use type anthropic with a built-in skill’s slug, such as xlsx, or type custom with a skill ID from List skills. version is optional and must be latest.
metadataobjectNoAn object whose only key is workspace_id, the ID of a workspace you work in. The API creates the agent in that workspace and does not store metadata.

Response

Returns 200 with the agent object. For every field, see Agents.

{
"id": "6f1c2a9e-0d4b-4c57-9a3e-2b7d8e1f4c60",
"archived_at": null,
"created_at": "2026-10-21T01:35:05.337Z",
"description": null,
"execution_identity": {
"type": "service_account"
},
"mcp_servers": [],
"metadata": {},
"model": {
"id": "default"
},
"multiagent": null,
"name": "Research Assistant",
"skills": [
{
"type": "anthropic",
"skill_id": "xlsx",
"version": "latest"
}
],
"system": "Answer from the attached files and cite them.",
"tools": [
{
"type": "agent_toolset_20260401",
"default_config": {
"enabled": true,
"permission_policy": {
"type": "always_allow"
}
},
"configs": [
{
"type": "bash",
"name": "bash",
"enabled": true,
"permission_policy": {
"type": "always_ask"
}
},
{
"type": "edit",
"name": "edit",
"enabled": true,
"permission_policy": {
"type": "always_allow"
}
},
{
"type": "read",
"name": "read",
"enabled": true,
"permission_policy": {
"type": "always_allow"
}
},
{
"type": "write",
"name": "write",
"enabled": true,
"permission_policy": {
"type": "always_allow"
}
},
{
"type": "glob",
"name": "glob",
"enabled": true,
"permission_policy": {
"type": "always_allow"
}
},
{
"type": "grep",
"name": "grep",
"enabled": true,
"permission_policy": {
"type": "always_allow"
}
},
{
"type": "web_fetch",
"name": "web_fetch",
"enabled": true,
"permission_policy": {
"type": "always_allow"
},
"url_sources": null
},
{
"type": "web_search",
"name": "web_search",
"enabled": false,
"permission_policy": {
"type": "always_ask"
}
}
]
}
],
"type": "agent",
"updated_at": "2026-10-21T01:35:05.337Z",
"version": 1
}

Errors

This endpoint can return these errors as well as the common errors.

Statuserror.typeCause and fix
400invalid_request_errorname is empty or over 100 characters, or model is missing. Send a name of 1 to 100 characters and a model.
400invalid_request_errormodel is not a model your deployment runs, or it sets effort, inference_geo or speed. Send default or a model ID only.
400invalid_request_errormetadata has a key other than workspace_id. Remove the other keys.
400invalid_request_errorThe body sends version, a non-empty mcp_servers, a multiagent that is not null, an execution_identity other than {type: "service_account"}, or a field this API does not take. Remove it.
400invalid_request_errortools has a custom tool, an mcp_toolset, a second agent_toolset_20260401 or a tool named twice. Send one built-in toolset that names each tool once.
400invalid_request_errorA permission_policy is auto. Use always_allow or always_ask.
400invalid_request_erroredit and write have different settings. Give them the same enabled and permission_policy, because the app has one setting for both.
400invalid_request_errorweb_search is enabled, or named without enabled: false. Leave it out or send enabled: false.
400invalid_request_errorA web_fetch or web_search config sets domain lists, max_content_tokens, url_sources or user_location. Send only name, enabled and permission_policy.
400invalid_request_errorA skill is listed twice, has a version other than latest, or names a built-in slug your deployment doesn’t have. List each skill once, by a built-in slug your deployment has or by a custom skill ID from List skills.
403permission_errorThis key lacks agents:write, is not a personal key, or has an Agent scope. Use a personal key with agents:write and no Agent scope.
403permission_errorYou don’t have permission to create agents in this organization, or you don’t work in the workspace metadata.workspace_id names, or no workspace has that ID. Ask an administrator for access, or name a workspace you work in.
403permission_errorA custom skill isn’t shared with the agent, and the API can’t share it for you. Name skills you own, or create the agent in the skill’s workspace.
404not_found_errormetadata.workspace_id is a workspace of another organization, or a custom skill you sent doesn’t exist or isn’t visible to the key’s owner. Check the IDs.

Example

cURL
curl -sS "$CONTEXT_BASE_URL/v1/agents" -H "x-api-key: $CONTEXT_API_KEY" -H "content-type: application/json" \
-d '{"name": "Research Assistant", "model": "default", "system": "Answer from the attached files and cite them.",
"tools": [{"type": "agent_toolset_20260401", "configs": [{"name": "bash", "permission_policy": {"type": "always_ask"}}]}],
"skills": [{"type": "anthropic", "skill_id": "xlsx"}]}'
Python
agent = client.beta.agents.create(
name="Research Assistant",
model="default",
system="Answer from the attached files and cite them.",
tools=[{
"type": "agent_toolset_20260401",
"configs": [{"name": "bash", "permission_policy": {"type": "always_ask"}}],
}],
skills=[{"type": "anthropic", "skill_id": "xlsx"}],
)
print(agent.id)
TypeScript
const agent = await client.beta.agents.create({
name: "Research Assistant",
model: "default",
system: "Answer from the attached files and cite them.",
tools: [{
type: "agent_toolset_20260401",
configs: [{ name: "bash", permission_policy: { type: "always_ask" } }],
}],
skills: [{ type: "anthropic", skill_id: "xlsx" }],
})
console.log(agent.id)