---
title: "Create an agent"
method: POST
path: "/agents"
tags: ["Agents"]
---

# Create an agent

`POST /agents`

## Request

- Base URL: `https://api.atako.ai`
- URL: `https://api.atako.ai/agents`
- Auth: HTTP bearer

Requires an active subscription and `canCreateAgents` permission. `teamId` may be ANY team of your live company; a team outside it (or belonging to no company) is only accepted if you belong to it — NOT_TEAM_MEMBER (403) otherwise. Guards, checked in order: NOT_TEAM_MEMBER (403), AGENT_CREATION_NOT_ALLOWED (403), AGENT_LIMIT_REACHED (403), NO_ACTIVE_SUBSCRIPTION (402), MODEL_NOT_FOUND/HARNESS_NOT_FOUND (400), CLIENT_NOT_FOUND (404).

## Request body

- CreateAgentBody
  - `name` string, required
  - `image` string, required: PNG filename under apps/web/public/aiygents/.
  - `finish` 'carbone' | 'chrome-studio' | 'titane' | 'candy' | 'nacre-ormeau' | 'velours' | 'ceramique' | 'marbre' | 'terrazzo' | 'cuir' | 'jade' | 'maille' | 'mercure' | 'lave' | 'eau' | 'glace' | 'malachite' | 'labradorite' | 'calacatta' | 'noyer' | 'soie' | 'ecailles', nullable: The 3D body finish (the user-facing « skin »). Absent or null = carbone; unknown → 400 FINISH_INVALID.
  - `mission` string, nullable: The agent's mission in 1–3 sentences, trimmed.
  - `systemPrompt` string, nullable: Free-text agent instructions, trimmed. Stored and sent to the orchestrator as-is (no business context appended).
  - `clientContext` string, nullable: Free-text per-agent business context, trimmed. Kept in its own column.
  - `modelId` string: Either an `ai_models` UUID (from GET /models or `aiModelId` in GET /models/catalog) or a raw OpenRouter slug (`slug` in GET /models/catalog, e.g. "mistralai/mistral-small"). A slug unknown to the catalog is rejected with 400. Omitted → admin-declared default model. With a direct-provider BYOK key (openai/anthropic), this is instead the provider's own model id.
  - `harnessId` string, uuid: From GET /harnesses.
  - `teamId` string, uuid, nullable: Assigns the agent to a shared team instead of keeping it personal.
  - `modelConfig` object: Per-task-type model overrides, forwarded to the orchestrator webhook.
    - `vision` string, nullable
    - `low_effort` string, nullable
    - `medium_effort` string, nullable
    - `high_effort` string, nullable
  - `engine` 'openclaw' | 'hermes' | 'opencode': Defaults to the platform default engine (hermes). `opencode` additionally requires `allowedRepos`.
  - `allowedRepos` string[]: Repositories (`owner/repo`) the agent may work on. REQUIRED (≥1) for `engine: opencode`, which also requires an active company GitHub connection; ignored by the other engines.
  - `llmKeyId` string, uuid: BYOK: id of a company LLM provider key (see docs — BYOK key management is not part of this customer API cut).

## Response `201`

The created agent (raw row).

- AgentRecord: The raw `agents` table row, returned verbatim by POST /agents (201) and POST /agents/{id}/end (200, under `.session`). Every column, including several operational/internal fields not otherwise exposed.
  - `id` string, uuid, required
  - `clientId` string, uuid, required
  - `teamId` string, uuid, nullable
  - `companyId` string, uuid, nullable
  - `name` string, required
  - `image` string, required
  - `systemPrompt` string, nullable: Raw user instructions (no business context appended).
  - `mission` string, nullable
  - `profileUpdatedAt` string, date-time
  - `modelId` string, uuid, nullable
  - `directModelId` string, nullable
  - `modelConfig` object, nullable: Per-task-type model overrides.
    - `vision` string, nullable
    - `low_effort` string, nullable
    - `medium_effort` string, nullable
    - `high_effort` string, nullable
  - `llmKeyId` string, uuid, nullable: Set for a BYOK agent (company LLM provider key); null for the platform key.
  - `harnessId` string, uuid, nullable
  - `engine` 'openclaw' | 'hermes' | 'opencode', required
  - `status` 'active' | 'completed' | 'paused' | 'provisioning' | 'unresponsive' | 'failed', required
  - `agentAuthTokenHash` string, nullable
  - `agentAuthIssuedAt` string, date-time, nullable
  - `agentAuthLastUsedAt` string, date-time, nullable
  - `startDate` string, date-time, required
  - `activatedAt` string, date-time, nullable
  - `endDate` string, date-time, nullable
  - `lastHeartbeatAt` string, date-time, nullable
  - `lastReadAt` string, date-time, nullable
  - `engineVersion` string, nullable
  - `engineImage` string, nullable
  - `engineRequestedVersion` string, nullable
  - `upgradingAt` string, date-time, nullable
  - `upgradeRequestedAt` string, date-time, nullable
  - `upgradeStatus` 'requested' | 'running' | 'succeeded' | 'failed', nullable
  - `upgradeError` string, nullable
  - `provisioningError` string, nullable
  - `pausedAt` string, date-time, nullable
  - `pausedReason` string, nullable
  - `clientContext` string, nullable: Per-agent "contexte business" free text.
  - `createdAt` string, date-time, required

## Other responses

- `400`: Missing/invalid field, unknown model/harness, or invalid engine.
- `401`: Missing, malformed, or invalid bearer token / API key, or revoked session (SESSION_REVOKED).
- `402`: NO_ACTIVE_SUBSCRIPTION
- `403`: AGENT_CREATION_NOT_ALLOWED / NOT_TEAM_MEMBER / AGENT_LIMIT_REACHED / BYOK_DISABLED / BYOK_NOT_ALLOWED
- `404`: CLIENT_NOT_FOUND / PROVIDER_KEY_NOT_FOUND

---

[API](https://skmtc.dev/atako/apis/atako-api.md) · [All operations](https://skmtc.dev/atako/apis/atako-api/llms.txt) · [OpenAPI document](https://skmtc.dev/atako/apis/atako-api/revisions/aa555c56fbd7?raw)
