> ## Documentation Index
> Fetch the complete documentation index at: https://docs.support.onclarity.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Manage agents

> Create and edit voice agents, publish drafts, and roll back to an earlier version.

Most teams build agents in Clarity's editor. The API is for the parts you want to script: creating agents from a template, changing a greeting or prompt in many agents at once, publishing after your own review, or rolling back.

## Drafts and published versions

An agent has numbered **versions**. Each version has a status:

| Status | Meaning |
| - | - |
| `published` | The version live calls use. One per agent. |
| `draft` | Your unpublished edits. At most one per agent. |
| `outdated` | A version that used to be published. You can republish it. |

**1. Edit**

`PATCH` an agent and your changes go to its draft. If there is no draft, Clarity creates one from the published version first. Live calls keep using the published version.

**2. Publish**

`POST …/publish` checks the draft against the full configuration rules. If it passes, the draft becomes the published version and the previous one becomes `outdated`.

**3. Roll back if needed**

`POST …/versions/{versionId}/republish` makes an `outdated` version live again.

> [!NOTE]
>
> Creating, editing, publishing, republishing and cloning agents need the publish permission, because they change what callers hear. Your organization API key has it.

## Endpoints

All paths are under `/v1/projects/{projectId}/agents`.

| Action | Request | Success |
| - | - | - |
| List agents | `GET /` | `200` `{ "agents": [...] }` |
| Read an agent | `GET /{id}` | `200` the agent: its draft if it has one, else its published version |
| Create an agent | `POST /` | `201` the agent, already published as version 1 |
| Edit the draft | `PATCH /{id}` | `200` the agent as edited |
| Publish the draft | `POST /{id}/publish` | `200` `{ "publishedVersion", "outdatedVersion" }` |
| Discard the draft | `POST /{id}/discard-draft` | `204` |
| List versions | `GET /{id}/versions` | `200` `{ "versions": [...] }` |
| Read a version | `GET /{id}/versions/{versionId}` | `200` the full version |
| Republish a version | `POST /{id}/versions/{versionId}/republish` | `200` `{ "publishedVersion", "outdatedVersion" }` |
| Clone an agent | `POST /{id}/clone` | `201` the new agent |
| Delete an agent | `DELETE /{id}` | `200` `{ "success": true, "message": "Agent deleted successfully" }` |

`GET /` leaves out Voice Assist agents. Add `?type=assist` for only those, or `?type=all` for every agent. Each listed agent shows its published configuration and carries `published_version_id`, `published_version_number` and `has_draft`.

## Create an agent

The prompt, `task_prompt_json`, is a rich-text document: paragraphs of `text` nodes. A `mention` node inserts a variable, such as a campaign item's `custom_vars` value.

```bash theme={null}
curl -X POST https://voice-api.onclarity.com/v1/projects/$PROJECT_ID/agents \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Renewals",
    "preferred_language": "English (US)",
    "greeting_message": "Hi, this is Clarity calling about your plan renewal.",
    "goodbye_message": "Thanks for your time. Goodbye!",
    "task_prompt_json": {
      "type": "doc",
      "content": [
        {
          "type": "paragraph",
          "content": [
            { "type": "text", "text": "You call customers whose plan renews soon. The customer is on the " },
            { "type": "mention", "attrs": { "id": "plan" } },
            { "type": "text", "text": " plan. Confirm they want to renew, and answer questions about pricing." }
          ]
        }
      ]
    }
  }'
```

The response is `201` with the new agent, including its `id`. The agent is published right away as version 1, so it can take calls once a number routes to it.

* `name` is required and must be unique in the project. A taken name answers `400`.
* Fields you leave out get Clarity's defaults. That includes the speech-recognition, language-model and voice settings in `agent_model_config`, which you can set later.
* To see the full set of fields an agent's configuration can carry, read `GET /v1/agents/config-schema`. It returns the JSON Schema every version is checked against when it is published.

> [!TIP]
>
> The simplest way to get a complete, valid configuration is to build an agent in Clarity's editor, then `GET` it and use the response as your template.

## Edit and publish

**1. Change the draft**

Send only the fields you want to change:

```bash theme={null}
curl -X PATCH https://voice-api.onclarity.com/v1/projects/$PROJECT_ID/agents/$AGENT_ID \
  -H "Authorization: Bearer $CLARITY_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{ "greeting_message": "Hello! This is Clarity, calling about your renewal." }'
```

The change is in the draft only. One exception: a new `name` applies to the agent at once.

**2. Publish**

```bash theme={null}
curl -X POST https://voice-api.onclarity.com/v1/projects/$PROJECT_ID/agents/$AGENT_ID/publish \
  -H "Authorization: Bearer $CLARITY_API_KEY"
```

```json theme={null}
{
  "publishedVersion": { "id": "b81f0c3e-…", "version_number": 2, "status": "published", "greeting_message": "Hello! This is Clarity, calling about your renewal." },
  "outdatedVersion": { "id": "a7c2e9d1-…", "version_number": 1, "status": "outdated", "greeting_message": "Hi, this is Clarity calling about your plan renewal." }
}
```

Both versions are trimmed here. The response may also carry `warnings`, for example about a language model that could not be verified. A publish with warnings still succeeds.

To throw the draft away instead, `POST /{id}/discard-draft`. Reading the agent then returns the published version again.

### Validation

Agents are checked twice:

* **When you save** (`POST`, `PATCH`), the body is checked field by field. A bad body answers `422` with every problem in `issues`:

  ```json theme={null}
  {
    "error": "goodbye_message: Too big: expected string to have <=500 characters",
    "issues": [
      { "path": "goodbye_message", "code": "too_big", "message": "Too big: expected string to have <=500 characters", "maximum": 500 }
    ]
  }
  ```

  Unknown fields are dropped without an error, so check the field names you send.

* **When you publish**, the complete configuration is checked against the runtime schema. A version that does not pass answers `422` and stays a draft:

  ```json theme={null}
  {
    "error": "schema_validation_failed",
    "message": "agent_model_config.tts_dialect: required for es (allowed: es, mx)",
    "details": [
      { "path": "agent_model_config.tts_dialect", "message": "required for es", "allowed": ["es", "mx"] }
    ]
  }
  ```

  `message` lists each problem with its path. `details` holds the same problems as objects.

Other publish and version errors:

| Status | `error` | When |
| - | - | - |
| `404` | `no_draft_to_publish` | Publish with no draft. |
| `404` | `no_draft_to_discard` | Discard with no draft. |
| `409` | `no_published_version` | Discard on an agent that was never published. |
| `409` | `draft_exists` | Republish while the agent has a draft. Publish or discard it first. |
| `409` | `version_not_outdated` | Republish of a version that is not `outdated`. `actualStatus` says what it is. |

## Versions and rollback

```bash theme={null}
curl https://voice-api.onclarity.com/v1/projects/$PROJECT_ID/agents/$AGENT_ID/versions \
  -H "Authorization: Bearer $CLARITY_API_KEY"
```

```json theme={null}
{
  "versions": [
    {
      "id": "b81f0c3e-5a2d-4e7f-9c1b-3d6a8e0f2b74",
      "agent_id": "5e1d7c2a-0f4b-4b8e-8c3d-9a6f2e1b7c40",
      "version_number": 2,
      "status": "published",
      "created_at": 1792504800000,
      "created_by_name": null,
      "updated_at": 1792504800000,
      "first_published_at": 1792505100000,
      "published_at": 1792505100000,
      "published_by_name": null
    },
    {
      "id": "a7c2e9d1-4b3f-4e6a-8d2c-1f0b9e8a7c65",
      "agent_id": "5e1d7c2a-0f4b-4b8e-8c3d-9a6f2e1b7c40",
      "version_number": 1,
      "status": "outdated",
      "created_at": 1792418400000,
      "created_by_name": null,
      "updated_at": 1792418400000,
      "first_published_at": 1792418400000,
      "published_at": 1792418400000,
      "published_by_name": null
    }
  ]
}
```

Versions are newest first. Times are milliseconds since the Unix epoch. The list is a summary; `GET /{id}/versions/{versionId}` returns a version's full configuration.

To roll back, republish an `outdated` version:

```bash theme={null}
curl -X POST https://voice-api.onclarity.com/v1/projects/$PROJECT_ID/agents/$AGENT_ID/versions/$VERSION_ID/republish \
  -H "Authorization: Bearer $CLARITY_API_KEY"
```

The version is checked against today's rules first, so a version that was valid when it was published can be refused with `422` if the rules have changed since.

Every conversation records the version that handled it (`agent_version_id`), so you can compare calls before and after a change. See [Conversations and recordings](/voice/conversations.md).

## Clone

`POST /{id}/clone` copies the agent's **published** version into a new agent named `<name> (clone)` (or `(clone 2)` and so on if that name is taken). The copy is published. An agent that was never published cannot be cloned (`409`).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.