# Create an agent

Creates a new agent (Concierge) as a draft in a workspace you own, with its own page at its username.

|  |  |
| --- | --- |
| REST | `POST /api/v1/agents` |
| MCP tool | `create_agent` |
| Classification | **Write** |
| Scope | `agents:create` |
| Minimum role on the agent | owner |
| Confirmation | Not needed |
| Retry safety | Send an `Idempotency-Key` header (REST) or `idempotency_key` argument (MCP) to retry safely |
| Success status | 201 |

## What it does

Creates a new agent (Concierge) as a draft in a workspace you own, with its own page at its username. It counts toward the plan limit of agents per brand (plan_limit when full). Without brand_id it goes under the only brand of your workspace; pass workspace_id or brand_id when you own several. Then configure it, test it and publish it. Needs agents:create and a token for all agents. Send an Idempotency-Key so a retry never creates two.

## Side effects

Creates a draft agent with its own page address and the caller as owner. Nothing is public until it is published. Counts toward the plan limit of agents per brand.

## Inputs

| Name | Type | Required | In | Description |
| --- | --- | --- | --- | --- |
| `name` | string | yes | body | Who the agent represents: a person or business name, like "Avery Quinn". |
| `username` | string | yes | body | The page address, 3 to 40 letters, digits or hyphens. Check it with check_username first. |
| `brand_id` | string | no | body | The brand to add it to, from list_workspaces. |
| `workspace_id` | string | no | body | The workspace to add it to, from list_workspaces, when it has one brand. |

## Example

REST:

```bash
curl -X POST "https://covo.lanaai.io/api/v1/agents" \
  -H "Authorization: Bearer $COVO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"name":"Avery Studio","username":"avery-studio"}'
```

MCP (POST /mcp):

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "create_agent",
    "arguments": {
      "name": "Avery Studio",
      "username": "avery-studio"
    }
  }
}
```

## Response

Returns an object with `id`, `name`, `represents`, `slug`, `status`, `role`, `workspace_id`, `brand_id`, `url` and `next_steps`. This is a real response, shortened to two items per list.

201 response:

```json
{
  "id": "agt_564e5e6bece6",
  "name": "Avery Studio's Concierge",
  "represents": "Avery Studio",
  "slug": "avery-studio",
  "status": "draft",
  "role": "owner",
  "workspace_id": "8e1b4ebc-bdd7-45c2-b80a-24d90f8ab3c1",
  "brand_id": "ff09d9cc-00e0-4c13-a9db-5b3dd8d18dfd",
  "url": "https://covo.lanaai.io/avery-studio",
  "next_steps": [
    "Fill in who it represents with update_agent_configuration (identity, personality, links, knowledge).",
    "Check it with validate_agent and run_agent_test."
  ]
}
```

Over MCP the same object comes back as the tool result, in `structuredContent` and as JSON text.

## Errors

| Status | Code | Meaning |
| --- | --- | --- |
| 401 | `unauthorized` | No token, or it is unknown, revoked or expired. OAuth apps refresh or reconnect. |
| 403 | `account_suspended` | The account that owns the token is paused. |
| 403 | `insufficient_scope` | The token lacks `agents:create`. |
| 400 | `bad_request` | An input is invalid; `field` names it. |
| 409, 422 | `idempotency_in_progress`, `idempotency_key_reused` | See Idempotency on the REST page. |
| 403 | `plan_limit` | The plan is full; `details` has the limit. |
| 429 | `rate_limited` | Wait `Retry-After` seconds. |
