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

# Agents

> Configured AI agents: prompt sections, variables, provider config, and the draft → published lifecycle.

An **agent** is a configured AI persona — its prompt, provider settings, tools, and custom variables. You create and publish an agent once, then bind it to [sessions](/concepts/sessions) and [campaigns](/concepts/campaigns).

## Anatomy

An agent is assembled from these fields:

| Field                         | Purpose                                                                                                                                                                   |
| ----------------------------- | ------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `objective`                   | Who the agent is and its high-level goal.                                                                                                                                 |
| `instruction`                 | Behavioral guidelines (tone, dos and don'ts).                                                                                                                             |
| `task`                        | The specific job to accomplish on the call.                                                                                                                               |
| `faqs`                        | Question/answer content to fold into the prompt.                                                                                                                          |
| `sample_conversations`        | Few-shot examples of the desired style.                                                                                                                                   |
| `custom_variables`            | Named placeholders (e.g. `callee_name`, `company`) filled per session.                                                                                                    |
| `config`                      | Provider selection and voice settings — see [Providers & Models](/concepts/providers).                                                                                    |
| `tools`                       | Names of tools the agent may call.                                                                                                                                        |
| `knowledge_base_id`           | The [knowledge base](/concepts/knowledge-base) this agent retrieves from.                                                                                                 |
| `pronunciation_dictionary_id` | Optional [pronunciation dictionary](/concepts/pronunciation-dictionaries) that rewrites how the agent says specific words, applied uniformly across every voice provider. |
| `sentiment_analysis`          | Opt-in post-call sentiment — below.                                                                                                                                       |
| `visibility`                  | `workspace` (shared with the workspace) or `private` (owner only).                                                                                                        |
| `channel`                     | `voice` or `whatsapp`. Chosen at creation and immutable afterward.                                                                                                        |

At dispatch time the prompt is assembled in a **fixed order** — Objective → Instructions → Task → FAQs → Samples — and placeholders are substituted from the session's `custom_variables`.

<Tip>
  Placeholders use the **double-brace** form only: `{{company}}`. Single braces, `[[company]]` and `$company` are left as literal text — they collide with ordinary prompt content like JSON snippets and prices such as "\$5".
</Tip>

## Post-call sentiment

Set `sentiment_analysis` to `{ "enabled": true }` and each finished call is classified as `positive`, `negative` or `neutral` from the customer's side of the transcript. The verdict appears as `sentiment` on the [session](/concepts/sessions), on a [call's](/concepts/calls) attempts, and in the `call_completed` [webhook](/guides/webhooks#outbound-webhooks).

It is opt-in per agent because it costs an extra model call per session, and it is skipped when the customer barely spoke — there is nothing to classify. It is independent of a campaign's qualification verdict: sentiment is how the customer *felt*, not whether they qualified.

## Lifecycle: draft → published

Agents are **immutable once published**. This guarantees a campaign always runs the exact configuration it was bound to.

```mermaid theme={null}
stateDiagram-v2
  [*] --> draft: POST /agent
  draft --> draft: PUT /agent/{id} (edit freely)
  draft --> published: POST /agent/{id}/publish
  published --> draft: POST /agent/{id}/clone (new draft)
```

* **Created `draft`** and fully editable via `PUT /agent/{id}`.
* **Publish** (`POST /agent/{id}/publish`) locks the config and makes the agent bindable by campaigns. One-way: `422` if the agent has no `name`, `409` if already published.
* **Once published**, `PUT` is rejected with `409`. To change a published agent, **clone it** (`POST /agent/{id}/clone`) — cloning always yields a new `draft`.
* **Campaigns bind only published agents.** Creating or updating a campaign with a `draft` agent returns `400`.
* **Deletion is guarded**: `DELETE /agent/{id}` returns `409` while any campaign still references the agent.

`status` (`draft` | `published`) and `published_at` are read-only response fields — `status` moves only through the publish endpoint, never as a body field.

<Note>
  Preview and testing (`GET /agent/{id}`, WhatsApp test-reply, and test sessions) work on drafts too — you don't need to publish to try an agent.
</Note>

## Visibility

* **`workspace`** agents are visible to everyone in the workspace.
* **`private`** agents are visible only to their owner (and admins). Personal copies of catalog agents are created `private` and suffixed "(My copy)".

## Endpoints

| Method | Path                                    | Scope            |
| ------ | --------------------------------------- | ---------------- |
| POST   | `/agent`                                | `sessions:write` |
| PUT    | `/agent/{agent_id}`                     | `sessions:write` |
| POST   | `/agent/{agent_id}/publish`             | `sessions:write` |
| POST   | `/agent/{agent_id}/clone`               | `sessions:write` |
| DELETE | `/agent/{agent_id}`                     | `sessions:write` |
| GET    | `/agent/all`                            | `sessions:read`  |
| GET    | `/agent/{agent_id}`                     | `sessions:read`  |
| POST   | `/agent/{agent_id}/whatsapp/test-reply` | `sessions:write` |

<CardGroup cols={2}>
  <Card title="Test your agent" icon="flask" href="/concepts/agent-testing">Simulate callers and grade the transcript before publishing.</Card>
  <Card title="Sessions" icon="phone" href="/concepts/sessions">Run an agent as a live call.</Card>
  <Card title="Providers & Models" icon="microchip" href="/concepts/providers">Configure LLM, STT, and TTS.</Card>
</CardGroup>
