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

# Voice Agent API

> Real-time voice agents that talk and listen. Configure an agent once, then deploy it to a browser, your own app, or the phone.

Talk to a voice agent in your browser in four commands, then put it on a phone number.

<CardGroup cols={2}>
  <Card title="Python starter" icon="python" href="https://github.com/AssemblyAI/voice-agent-starter-python">
    Python 3.9+, standard library only.
  </Card>

  <Card title="JavaScript starter" icon="js" href="https://github.com/AssemblyAI/voice-agent-starter-js">
    Node 18+, no dependencies.
  </Card>
</CardGroup>

## Step 1: Clone

<CodeGroup>
  ```bash Python theme={null}
  git clone https://github.com/AssemblyAI/voice-agent-starter-python
  cd voice-agent-starter-python
  cp .env.example .env
  ```

  ```bash JavaScript theme={null}
  git clone https://github.com/AssemblyAI/voice-agent-starter-js
  cd voice-agent-starter-js
  cp .env.example .env
  ```
</CodeGroup>

## Step 2: Add your key

Paste your [API key](https://www.assemblyai.com/dashboard/api-keys) into `.env`:

```bash .env theme={null}
ASSEMBLYAI_API_KEY=<your-key>
```

## Step 3: Publish the starter agent

<CodeGroup>
  ```bash Python theme={null}
  python publish.py
  ```

  ```bash JavaScript theme={null}
  npm run publish
  ```
</CodeGroup>

Publishes the starter agent to your account and saves its ID for the next step.

## Step 4: Talk to it

<CodeGroup>
  ```bash Python theme={null}
  python deployment/browser/server.py
  ```

  ```bash JavaScript theme={null}
  npm start
  ```
</CodeGroup>

Open `http://localhost:3000` in Chrome or Edge and start talking.

## Put it on a phone number

Twilio passes calls to AssemblyAI over SIP, so there's no media server or webhook to run. Buy a Twilio number, then add your credentials and a trunk domain you invent:

```bash .env theme={null}
TWILIO_ACCOUNT_SID=AC...                          # console.twilio.com, top of the page
TWILIO_AUTH_TOKEN=your_token_here                 # same place, hidden until you click it
TWILIO_PHONE_NUMBER=+1...                         # a number already in your account, E.164
TWILIO_TRUNK_DOMAIN=acme-agent.pstn.twilio.com    # a name you invent, unique across Twilio
```

<CodeGroup>
  ```bash Python theme={null}
  python deployment/telephony/connect.py
  ```

  ```bash JavaScript theme={null}
  npm run phone
  ```
</CodeGroup>

That creates the SIP trunk on your domain, routes it to AssemblyAI, attaches your number to it, and binds your agent. Every step checks for existing state first, so it's safe to re-run.

Call the number.

## Next steps

<AccordionGroup>
  <Accordion title="Write your own agent">
    Every file in `agents/` is the request body for [`POST /v1/agents`](/docs/voice-agents/voice-agent-api/api-spec/create-agent), sent unchanged. The starter agent is four fields:

    ```json agents/minimal.jsonc theme={null}
    {
      "name": "Minimal agent",
      "system_prompt": "You are a friendly assistant on a voice call. Keep every reply to one or two short sentences. Answer what was asked, lead with the answer, and skip the preamble. If you don't know something, say so. No exclamation marks.",
      "voice": { "voice_id": "anna" },
      "greeting": "Hey, what can I do for you?"
    }
    ```

    Copy the closest file to start your own (`cp agents/http-tools.jsonc agents/my-agent.jsonc`). Every field is commented. Publish again and both the browser tab and the phone number pick up the change on the next call.
  </Accordion>

  <Accordion title="Publish one of the other agents">
    Nine agents ship with each starter. Set `AGENT=` to pick one:

    | `AGENT=`       | Demonstrates                                                                              | Requires           |
    | -------------- | ----------------------------------------------------------------------------------------- | ------------------ |
    | `minimal`      | The three required fields, and the defaults applied to the rest                           |                    |
    | `keyterms`     | Biasing transcription toward names and jargon                                             |                    |
    | `turn-taking`  | Silence thresholds and interruption handling                                              |                    |
    | `byo-llm`      | Claude through the AssemblyAI gateway, or your own endpoint                               |                    |
    | `http-tools`   | Tools that AssemblyAI calls on the agent's behalf                                         |                    |
    | `exa-search`   | Web search during a call                                                                  | `EXA_API_KEY`      |
    | `airtable-crm` | Reading a caller record and writing one back                                              | `AIRTABLE_*`       |
    | `cal-booking`  | Checking availability, then booking a slot                                                | `CAL_*`            |
    | `dtmf`         | PCI compliance: card entry on the keypad, never in the transcript, the logs, or the model | `DTMF_WEBHOOK_URL` |

    <CodeGroup>
      ```bash Python theme={null}
      AGENT=cal-booking python publish.py
      python deployment/browser/server.py
      ```

      ```bash JavaScript theme={null}
      AGENT=cal-booking npm run publish
      npm start
      ```
    </CodeGroup>
  </Accordion>

  <Accordion title="Give an agent your API keys">
    Values written as `${VAR}` in an agent file are substituted at publish time from `.env`, or from `agents/<name>.env` for credentials only one agent uses. Both are gitignored, so the JSON is safe to commit.
  </Accordion>

  <Accordion title="Put the browser app online">
    Deploy the [Python](https://render.com/deploy?repo=https://github.com/AssemblyAI/voice-agent-starter-python) or [JavaScript](https://render.com/deploy?repo=https://github.com/AssemblyAI/voice-agent-starter-js) starter to Render. It prompts for `ASSEMBLYAI_API_KEY` and nothing else.

    Anyone with the URL can start sessions billed to that key.
  </Accordion>
</AccordionGroup>

<CardGroup cols={3}>
  <Card title="1. Create" icon="plus" href="/docs/voice-agents/voice-agent-api/create-agent">
    Create a reusable agent with one REST call, then update, list, and delete it.
  </Card>

  <Card title="2. Configure" icon="sliders" href="/docs/voice-agents/voice-agent-api/prompting-guide">
    Shape how it sounds and behaves: prompt, voice, greeting, audio, turn detection, keyterms, tools.
  </Card>

  <Card title="3. Deploy" icon="rocket" href="/docs/voice-agents/voice-agent-api/deploy">
    Connect by `agent_id` over the API, from a browser, or to a phone number with Twilio.
  </Card>
</CardGroup>

Or jump straight to a topic:

* [Add tools](/docs/voice-agents/voice-agent-api/tools/overview): server-side HTTP tools and client-side function tools
* [Connect your own LLM](/docs/voice-agents/voice-agent-api/connect-your-own-llm): point the agent at an OpenAI-compatible model
* [Manage agents (REST)](/docs/voice-agents/voice-agent-api/manage-agents): every endpoint, field, and validation rule
* [Browser integration](/docs/voice-agents/voice-agent-api/browser-integration): mint tokens and build your own client
* [Phone agents over SIP](/docs/voice-agents/voice-agent-api/connect-to-twilio): the phone step above in full, including a Twilio CLI path
* [Events reference](/docs/voice-agents/voice-agent-api/events-reference): every WebSocket event with full payloads
* [Build with AI coding tools](/docs/voice-agents/voice-agent-api/build-with-ai-tools): point Claude Code, Cursor, or v0 at these docs
* [Troubleshooting](/docs/voice-agents/voice-agent-api/troubleshooting): symptom-to-fix table and support logging

No code at all? Talk to an agent in the [Voice Agent playground](https://www.assemblyai.com/dashboard/playground/voice-agent).
