# Apply a draft

Applies an open draft to the live agent, saving an automatic version first.

|  |  |
| --- | --- |
| REST | `POST /api/v1/agents/{agent_id}/drafts/{draft_id}/apply` |
| MCP tool | `apply_draft` |
| Classification | **Sensitive write** |
| Scope | `agents:write` |
| Minimum role on the agent | editor |
| Confirmation | Required: `confirm: true`, after the person agrees |
| Retry safety | Send an `Idempotency-Key` header (REST) or `idempotency_key` argument (MCP) to retry safely |
| Success status | 200 |

## What it does

Applies an open draft to the live agent, saving an automatic version first. Refuses with version_conflict if the agent changed after the draft was written, unless force is true. Removals need confirm: true.

## Side effects

Saves a version, then applies the draft to the configuration. If the agent is published, visitors see it at once.

## Inputs

| Name | Type | Required | In | Description |
| --- | --- | --- | --- | --- |
| `agent_id` | string | yes | path | The agent id (agt_...), from list_agents. |
| `draft_id` | string | yes | path | The draft id. |
| `force` | boolean | no | body | Apply even though the agent changed since the draft was written. Default false. |
| `confirm` | true | no | body | Set to true after reviewing the effect with the person you work for. Required for destructive operations. |

## Example

REST:

```bash
curl -X POST "https://covo.lanaai.io/api/v1/agents/agt_4edc89bb2964/drafts/80da083a-0818-47b5-afc4-ef5b39c59137/apply" \
  -H "Authorization: Bearer $COVO_TOKEN" \
  -H "Content-Type: application/json" \
  -H "Idempotency-Key: $(uuidgen)" \
  -d '{"confirm":true}'
```

MCP (POST /mcp):

```json
{
  "jsonrpc": "2.0",
  "id": 1,
  "method": "tools/call",
  "params": {
    "name": "apply_draft",
    "arguments": {
      "agent_id": "agt_4edc89bb2964",
      "draft_id": "80da083a-0818-47b5-afc4-ef5b39c59137",
      "confirm": true
    }
  }
}
```

## Response

Returns an object with `draft_id`, `status`, `applied`, `revision`, `previous_revision`, `changes`, `backup_version` and `validation`. This is a real response, shortened to two items per list.

200 response:

```json
{
  "draft_id": "80da083a-0818-47b5-afc4-ef5b39c59137",
  "status": "applied",
  "applied": true,
  "revision": 7,
  "previous_revision": 6,
  "changes": [
    {
      "path": "personality.greeting",
      "operation": "replace",
      "before": "I'm Avery Quinn's Concierge. I can help you learn about Avery Quinn's work, what's on offer, or anything else you're curious about.",
      "after": "Hi, I am Avery’s Concierge. Ask me about spring projects."
    }
  ],
  "backup_version": 2,
  "validation": {
    "valid": true,
    "state": "ready",
    "errors": [],
    "warnings": [
      {
        "step": "knowledge",
        "field": null,
        "severity": "recommended",
        "message": "Add a few common questions. Short, specific answers work best."
      },
      {
        "step": "publish",
        "field": null,
        "severity": "recommended",
        "message": "Ask the preview a question before you publish."
      }
    ]
  }
}
```

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:write`. |
| 404 | `agent_not_found` | Unknown agent, or not reachable with this token. |
| 400 | `bad_request` | An input is invalid; `field` names it. |
| 409 | `confirmation_required` | Review the effect with the person you work for, then send `confirm: true`. |
| 409, 422 | `idempotency_in_progress`, `idempotency_key_reused` | See Idempotency on the REST page. |
| 429 | `rate_limited` | Wait `Retry-After` seconds. |
