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

# Agents

> An agent is the voice AI your callers talk to — it has a personality, a voice, and a set of actions it can take.

## What is an agent?

An agent is a complete voice persona. When you create one with just a name, it is immediately usable — OneInbox automatically sets up a default LLM, a default voice, and a default system prompt. You only need to change these if you want to customise them.

| Component          | Default                                   | Change it when...                                                |
| ------------------ | ----------------------------------------- | ---------------------------------------------------------------- |
| **LLM** (AI brain) | Auto-created with a general system prompt | You want a specific persona, script, or temperature              |
| **Voice**          | Default voice pre-configured              | You want a specific voice from ElevenLabs or Cartesia            |
| **System prompt**  | General-purpose assistant                 | You want the agent to follow specific instructions or scripts    |
| **Language**       | `en`                                      | You need the agent to transcribe a different language            |
| **Tools**          | None                                      | You want the agent to take actions (SMS, transfer, capture data) |

A single agent handles browser calls (via the Web SDK) and direct phone calls — both outbound and inbound — you don't need a separate agent per call type.

***

## Create an agent

You have two options — create with defaults and customise later, or provide your own config upfront. Both produce a fully working agent.

### Option A — Create with defaults

Just a name. OneInbox automatically creates a default LLM, voice, and system prompt. Customise later using the `llm_id` and `agent_id` from the response.

```bash theme={null}
curl -X POST https://api.oneinbox.ai/v1/agents \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "name": "Acme Support Agent" }'
```

```json theme={null}
{
  "id": "agt_abc123",
  "name": "Acme Support Agent",
  "llm_id": "llm_xyz789",
  "created_at": "2026-06-01T10:00:00Z"
}
```

### Option B — Create with your own config

Pass any fields you want configured from the start. All fields except `name` are optional.

```bash theme={null}
curl -X POST https://api.oneinbox.ai/v1/agents \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Acme Support Agent",
    "language": "en",
    "first_message": "Hi! Thanks for reaching out to Acme. How can I help you today?",
    "tts": {
      "provider": "elevenlabs",
      "voice_id": "<imported_voice_id>"
    },
    "silence_timeout_seconds": 10,
    "max_duration_seconds": 600,
    "interruption_sensitivity": 0.6,
    "enable_recording": true,
    "voicemail_detection": true,
    "voicemail_message": "Hi, please leave a message and we'll call you back."
  }'
```

The `llm_id` in the response is the auto-created AI model. Use it to set the system prompt, attach tools, or link knowledge bases — regardless of which option you used.

Your agent is ready immediately. Test it with a quick browser call — no phone number needed, runs entirely over the internet (same mechanism the [Web SDK](/concepts/web-sdk) uses):

```bash theme={null}
curl -X POST https://api.oneinbox.ai/v1/calls/web \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "agent_id": "agt_abc123" }'
```

***

## Customise the defaults

Out of the box the agent works with a general-purpose system prompt, a default voice, and a default LLM. To give your agent a specific personality or script, update the LLM model using the `llm_id` from the create response:

```bash theme={null}
curl -X PATCH https://api.oneinbox.ai/v1/models/<llm_id> \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "system_prompt": "You are a helpful sales rep for Acme Corp. Your goal is to qualify leads and book product demos. Keep all replies under two sentences. Be warm and direct.",
    "temperature": 0.7
  }'
```

Changes apply to new calls immediately. One LLM model can power multiple agents — to share a brain across agents, PATCH the agent with `{ "llm_id": "llm_xyz789" }`. Update the model once and all agents using it pick up the change.

To use a self-hosted or third-party LLM, set `provider` to `"custom"` and supply `custom_websocket_url`. The URL can be `wss://`, `ws://`, `https://`, or `http://` — the server must expose an OpenAI-compatible streaming chat completions interface.

```bash theme={null}
curl -X POST https://api.oneinbox.ai/v1/models \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "My self-hosted LLM",
    "provider": "custom",
    "custom_websocket_url": "wss://your-llm-server.example.com/v1/chat/completions",
    "system_prompt": "You are a helpful voice assistant.",
    "temperature": 0.7
  }'
```

***

## Browse available models

The catalogue lists accepted model IDs for LLM, STT, and TTS providers — useful before setting a custom model on your agent or LLM.

```bash theme={null}
# LLM providers — openai, anthropic, groq
curl "https://api.oneinbox.ai/v1/models/catalogue?provider=openai" \
  -H "Authorization: Bearer <api_key>"

# STT providers — deepgram, assembly_ai
curl "https://api.oneinbox.ai/v1/models/catalogue?provider=deepgram" \
  -H "Authorization: Bearer <api_key>"

# TTS providers — cartesia, elevenlabs, openai
curl "https://api.oneinbox.ai/v1/models/catalogue?provider=cartesia" \
  -H "Authorization: Bearer <api_key>"
```

The `source` field on each item is `live` (fetched directly from the provider), `seed` (a static list shown without a credential), or `unverified`.

***

## Give your agent tools

Tools (send SMS, capture caller data, transfer calls, book meetings, etc.) are attached to the **LLM model**, not the agent directly.

**Why:** the LLM model is what decides what to do during a conversation. Tools are the actions it can take — so they live there. Any agent using that model inherits all its tools automatically.

To add a tool, first create it, then attach it to the `llm_id` from your agent:

```bash theme={null}
# 1. Create a tool (example: capture caller info)
curl -X POST https://api.oneinbox.ai/v1/tools \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "capture_lead_info",
    "type": "extract_information",
    "description": "Extract the caller name, budget, and timeline from the conversation.",
    "extraction_schema": {
      "fields": [
        { "name": "caller_name", "type": "string", "description": "Full name of the caller" },
        { "name": "budget", "type": "string", "description": "Budget the caller mentioned" },
        { "name": "timeline", "type": "string", "description": "Their decision timeline" }
      ]
    }
  }'
# Save the returned tool "id"

# 2. Attach it to the agent's LLM model
curl -X PATCH https://api.oneinbox.ai/v1/models/<llm_id> \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "tool_ids": ["<tool_id>"] }'
```

→ [Tools guide](/guides/tools) — all 7 tool types with full examples

***

## Speech-to-text (STT)

STT converts the caller's voice into text that the LLM can understand. Set the `transcriber` object on the agent to choose the provider and model.

All STT providers below are platform-provided — no credential needed.

| Provider       | Models                                      | Best for                                                            |
| -------------- | ------------------------------------------- | ------------------------------------------------------------------- |
| **Deepgram**   | `nova-3` (default), `flux-en`, `flux-multi` | Low latency, high accuracy. `nova-3` recommended for most use cases |
| **Whisper**    | `whisper-1`                                 | Broad language coverage                                             |
| **AssemblyAI** | `best`, `nano`, `slam-1`                    | High accuracy for complex audio                                     |
| **Azure**      | e.g. `en-US-JennyNeural`                    | Enterprise Azure deployments                                        |

```bash theme={null}
curl -X PATCH https://api.oneinbox.ai/v1/agents/<agent_id> \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "transcriber": {
      "provider": "deepgram",
      "model": "nova-3",
      "language": "en"
    }
  }'
```

Set `language` to match the caller's language — e.g. `"hi"` for Hindi, `"ja"` for Japanese. Use `flux-multi` for multilingual calls where the language is unknown.

***

## Text-to-speech (TTS)

TTS converts the agent's text replies into spoken audio. Set the `tts` object on the agent to choose the provider, voice, and speed.

All TTS providers below are platform-provided — no credential needed.

| Provider       | Notable voices              | Best for                              |
| -------------- | --------------------------- | ------------------------------------- |
| **Cartesia**   | Sarah, Liam, Barbershop Man | Ultra-low latency, natural prosody    |
| **Deepgram**   | Thalia, Asteria, Zeus       | Fast, conversational                  |
| **ElevenLabs** | Roger, Laura, Alice         | High expressiveness, emotional range  |
| **OpenAI**     | Alloy, Echo, Nova, Shimmer  | Consistent quality, stable under load |
| **Minimax**    | Female Phone, Male Phone    | Optimised for phone-quality audio     |
| **Shisa**      | JA Female                   | Japanese language specialisation      |

```bash theme={null}
curl -X PATCH https://api.oneinbox.ai/v1/agents/<agent_id> \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "tts": {
      "provider": "cartesia",
      "voice_id": "<vc_...>",
      "speed": 1.0,
      "stability": 0.5
    }
  }'
```

<Note>
  `voice_id` must be the `vc_...` ID from the `/v1/voices` endpoint — not the raw provider voice ID. See [Voices](/guides/voices) for the full list of available voice IDs.
</Note>

| Field       | Range   | What it does                                                              |
| ----------- | ------- | ------------------------------------------------------------------------- |
| `voice_id`  | —       | The OneInbox voice ID (`vc_...`) from `/v1/voices`                        |
| `speed`     | 0.5–2.0 | Playback rate. `1.0` is normal speech speed                               |
| `stability` | 0.0–1.0 | Voice consistency. Higher = more consistent tone, lower = more expressive |

***

## Key agent fields

| Field                      | Default | What it controls                                                                                                                                    |
| -------------------------- | ------- | --------------------------------------------------------------------------------------------------------------------------------------------------- |
| `first_message`            | —       | First thing the agent says when a call connects. Keep it under 2 sentences                                                                          |
| `language`                 | `en`    | Transcription language. Set at the agent level — `{ "language": "ar" }`                                                                             |
| `silence_timeout_seconds`  | `10`    | Seconds of silence before the call ends                                                                                                             |
| `max_duration_seconds`     | `600`   | Hard cap on call length. Range: 30–7200                                                                                                             |
| `interruption_sensitivity` | `0.5`   | How easily the caller can interrupt (0.0 = hard, 1.0 = very easy)                                                                                   |
| `responsiveness`           | `0.5`   | How quickly the agent responds after the caller stops speaking (0 = patient, 1 = snappy)                                                            |
| `enable_recording`         | `false` | Set `true` to get `recording_url` in the call record after the call ends                                                                            |
| `voicemail_detection`      | `false` | Detect voicemail greetings on outbound calls                                                                                                        |
| `voicemail_message`        | —       | What the agent says if voicemail is detected                                                                                                        |
| `end_call_phrases`         | `[]`    | Phrases that trigger call end automatically — e.g. `["goodbye", "talk later"]`                                                                      |
| `job_description`          | —       | Prepended to the system prompt as a `# Role` block at call time. Use this to set the agent's role without editing the full system prompt on the LLM |
| `speed`                    | `1.0`   | Top-level speech rate multiplier (0.5–2.0). Overrides `tts.speed` when set                                                                          |
| `background_sound`         | —       | Ambient audio behind the agent's voice — e.g. `"office"`, `"cafe"`                                                                                  |
| `emotions`                 | `false` | Enable emotion-aware voice expression (provider-dependent)                                                                                          |

***

## Dynamic variables

Dynamic variables let you personalise an agent's `first_message`, `voicemail_message`, and `system_prompt` per call — without creating a separate agent per lead. Write placeholders with **single braces** (`{variable_name}`) in any of those fields, then pass the actual values when you start the call.

```bash theme={null}
# 1. Agent with placeholders
curl -X POST https://api.oneinbox.ai/v1/agents \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "name": "Sales Bot",
    "first_message": "Hi {lead_name}, this is Aria calling about {product_name}.",
    "dynamic_variables": {
      "product_name": "Acme Outreach"
    }
  }'

# 2. Call with per-call values
curl -X POST https://api.oneinbox.ai/v1/calls \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "agent_id": "<agent_id>",
    "to_number": "+919876543210",
    "from_number": "+15739693824",
    "variables": {
      "lead_name": "Priya"
    }
  }'
```

The agent opens with: **"Hi Priya, this is Aria calling about Acme Outreach."**

**Two layers — how they combine:**

| Layer                            | Where set                          | Priority                          |
| -------------------------------- | ---------------------------------- | --------------------------------- |
| `dynamic_variables` on the agent | Agent config — same for every call | Lower (default fallback)          |
| `variables` on the call          | Call request — per-call            | Higher (overrides agent defaults) |

At call start, OneInbox builds the final variable map by merging both layers (call values win on collision), then substitutes every `{placeholder}` in the templates before the agent says a word. The LLM and TTS only ever see the resolved strings — never the raw placeholders.

<Note>
  Use **single braces** — `{lead_name}`, not `{{lead_name}}`. Double braces are not interpolated and appear as literal text.
</Note>

***

## Updating an agent

Update any field on an agent at any time. Changes take effect on the next call — active calls in progress are not affected.

```bash theme={null}
curl -X PATCH https://api.oneinbox.ai/v1/agents/<agent_id> \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{
    "first_message": "Hi! How can I help you today?",
    "silence_timeout_seconds": 15
  }'
```

***

## Manage agents

### List all agents

Retrieve all agents in your account. Use this to find an `agent_id` or `llm_id` you need for other operations.

```bash theme={null}
curl "https://api.oneinbox.ai/v1/agents?limit=20" \
  -H "Authorization: Bearer <api_key>"
```

### Get a specific agent

Fetch a single agent's full config — including `llm_id`, language, voice settings, and all behaviour fields.

```bash theme={null}
curl https://api.oneinbox.ai/v1/agents/<agent_id> \
  -H "Authorization: Bearer <api_key>"
```

The single-agent GET includes a read-only `effective_system_prompt` field — the exact system prompt the agent is given at call time: the LLM's `system_prompt` with `job_description` prepended as a `# Role` block. This is what the LLM actually receives, assembled the same way the worker does at runtime.

```json theme={null}
{
  "id": "agt_abc123",
  "llm_id": "llm_xyz789",
  "job_description": "You are a friendly sales rep at Acme.",
  "effective_system_prompt": "# Role\nYou are a friendly sales rep at Acme.\n\nYou are a helpful voice assistant.",
  "..."
}
```

<Note>
  `effective_system_prompt` is only populated on `GET /v1/agents/{id}`. It is `null` on the list endpoint to avoid an LLM lookup per row. Per-call variable interpolation and knowledge base chunks are resolved at runtime and are not reflected here.
</Note>

### Delete an agent

Permanently removes the agent. If the agent is assigned to a phone number, reassign the number to a different agent first, then delete.

```bash theme={null}
# 1. Reassign the phone number first (if applicable)
curl -X PATCH https://api.oneinbox.ai/v1/phone-numbers/<phone_id> \
  -H "Authorization: Bearer <api_key>" \
  -H "Content-Type: application/json" \
  -d '{ "agent_id": "<different_agent_id>" }'

# 2. Then delete the agent
curl -X DELETE https://api.oneinbox.ai/v1/agents/<agent_id> \
  -H "Authorization: Bearer <api_key>"
```

### List LLM models

```bash theme={null}
curl "https://api.oneinbox.ai/v1/models?limit=20" \
  -H "Authorization: Bearer <api_key>"
```

### Get an LLM model

Fetch the full config of a specific model — system prompt, tools, knowledge bases, and custom URL.

```bash theme={null}
curl https://api.oneinbox.ai/v1/models/<model_id> \
  -H "Authorization: Bearer <api_key>"
```

### Delete an LLM model

Permanently removes the model. Agents currently using this model will lose their LLM config — reassign them first with `{ "llm_id": "<replacement_model_id>" }`.

```bash theme={null}
curl -X DELETE https://api.oneinbox.ai/v1/models/<model_id> \
  -H "Authorization: Bearer <api_key>"
```

***

## Next steps

<CardGroup cols={2}>
  <Card title="Tools" icon="wrench" href="/guides/tools">
    Give your agent actions — SMS, email, data capture, transfer
  </Card>

  <Card title="Phone numbers" icon="phone" href="/guides/phone-calls">
    Make real outbound calls with a registered phone number
  </Card>

  <Card title="Calls" icon="chart-bar" href="/guides/call-outcomes">
    How calls are classified and how to read results
  </Card>

  <Card title="Voices" icon="microphone" href="/guides/voices">
    Browse available voices and configure TTS
  </Card>
</CardGroup>
