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

# Voice (Vapi Telephony)

> Give your AI agent a phone number — same brain, voice-adapted

Voice lets you give your AI agent a real phone number. Callers interact with the same agent as on your website — same corpus, same tools, same personality — but through natural speech.

<Note>
  Voice calls use the exact same corpus, segments, system prompt, and tools as the chat widget. There is no separate configuration for voice content — changes to your knowledge base apply to both channels instantly.
</Note>

## Architecture

```
Phone call
  → Vapi (STT: Deepgram)
    → Animam Custom LLM endpoint (POST /voice/{slug}/chat)
      → SSE stream
        → Vapi (TTS)
          → Phone call
```

**Animam is the brain, not the media stack.** Animam acts as a **Custom LLM**: your voice orchestrator sends conversation turns as OpenAI-format messages, and Animam responds with an SSE stream. The hard real-time work — speech-to-text, text-to-speech, turn-taking, the telephony/SIP signalling — is handled by the voice layer. That separation is deliberate: it lets you choose how much you manage.

## Three ways to connect telephony

Pick the level of control you want. All three use the same Animam brain.

### Level 1 — Managed (no-code)

Animam creates the Vapi assistant **and** buys a phone number using the platform's own Vapi key. Your tenant never touches Vapi.

```bash theme={null}
curl -X POST https://api.animam.ai/tenants/your-slug/voice/setup \
  -H "Authorization: Bearer ak_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "language": "fr",
    "voiceId": "aura-luna-fr",
    "firstMessage": "Bonjour, comment puis-je vous aider ?",
    "buyNumber": true,
    "numberAreaCode": "33"
  }'
# → { assistantId, phoneNumber, customLlmUrl, serverUrl }
```

### Level 2 — Bring your own Vapi (and your own SIP / carrier)

You run your own Vapi account. Import **your** SIP trunk or phone numbers there (Vapi supports BYO carriers — Twilio, Telnyx, your own SIP), point the assistant's **Custom LLM URL** at `https://api.animam.ai/voice/your-slug`, then link it to Animam:

```bash theme={null}
curl -X PUT https://api.animam.ai/tenants/your-slug/voice/setup \
  -H "Authorization: Bearer ak_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "assistantId": "your_vapi_assistant_id",
    "phoneNumber": "+33123456789",
    "language": "fr"
  }'
```

This is the "I manage my own telephony" path: **your SIP lives in your Vapi**, Animam stays the brain. There is no SIP endpoint to configure on Animam's side — and there doesn't need to be.

### Level 3 — Bring your own voice platform

The Custom LLM endpoint is plain **OpenAI-compatible** — it isn't Vapi-specific. Any orchestrator that supports a Custom LLM URL works: Vapi, LiveKit Agents, Pipecat, Retell, Bland, or your own stack. Point its model URL at `https://api.animam.ai/voice/your-slug` (it calls `/chat/completions`, SSE), and Animam answers with the same corpus, tools and personality. You own the SIP, the STT/TTS and the latency budget; Animam owns the reasoning.

## Tenant Settings

| Field              | Type    | Description                      |
| ------------------ | ------- | -------------------------------- |
| `voiceEnabled`     | boolean | Enable/disable the voice channel |
| `voiceProvider`    | string  | Always `"vapi"` for now          |
| `voicePhoneNumber` | string  | E.164 format phone number        |
| `voiceAssistantId` | string  | Vapi assistant ID                |
| `voiceConfig`      | object  | Voice behavior (see below)       |

### voiceConfig Fields

| Field             | Type      | Description                                                                 |
| ----------------- | --------- | --------------------------------------------------------------------------- |
| `voiceId`         | string    | Vapi/Deepgram voice ID (e.g. `"shimmer"`, `"alloy"`)                        |
| `language`        | string    | BCP-47 language code (e.g. `"fr-FR"`, `"en-US"`)                            |
| `firstMessage`    | string    | First words spoken when a call connects                                     |
| `endCallPhrases`  | string\[] | Phrases that trigger call end (e.g. `["au revoir", "merci bonne journée"]`) |
| `maxCallDuration` | integer   | Maximum call duration in seconds                                            |

## Endpoints

### POST /voice/{slug}/chat

**Custom LLM endpoint for Vapi.** Receives OpenAI-format messages and streams back a response in SSE format. Not intended for direct use — Vapi calls this automatically.

```bash theme={null}
# Example of what Vapi sends:
curl -X POST https://api.animam.ai/voice/your-slug/chat \
  -H "Authorization: Bearer ak_your_token" \
  -H "Content-Type: application/json" \
  -d '{
    "messages": [
      { "role": "user", "content": "Bonjour, je voudrais prendre rendez-vous" }
    ],
    "stream": true
  }'
```

### POST /voice/{slug}/events

**Webhook endpoint for Vapi events.** Handles lifecycle events from Vapi:

| Event                | Description                                       |
| -------------------- | ------------------------------------------------- |
| `assistant-request`  | Vapi requesting assistant config at call start    |
| `tool-calls`         | Tool execution during a call (same tools as chat) |
| `status-update`      | Call state changes (ringing, in-progress, ended)  |
| `end-of-call-report` | Full call summary after hang-up                   |

Configure this URL in your Vapi dashboard under **Assistant > Server URL**:

```
https://api.animam.ai/voice/your-slug/events
```

### GET /voice/{slug}/recordings/{callId}

Download a call recording (if recording is enabled in Vapi).

```bash theme={null}
curl https://api.animam.ai/voice/your-slug/recordings/call_abc123 \
  -H "Authorization: Bearer ak_your_token" \
  --output call.mp3
```

## Tools During Voice Calls

All tools configured for your tenant work during voice calls:

* **SUBMIT\_FORM** — Agent collects info verbally, submits the form at end of call
* **BOOK\_MEETING** — Agent checks availability and confirms a booking during the call
* **CHECK\_AVAILABILITY** — Agent reads out available time slots
* **ESCALATE\_TO\_HUMAN** — Agent offers to transfer to a human operator

The agent adapts its language for voice — it reads out structured data (dates, prices, addresses) in a natural spoken format rather than displaying formatted text.

## Verifying Your Setup

```bash theme={null}
# Check voice is enabled
curl https://api.animam.ai/tenants/your-slug \
  -H "Authorization: Bearer ak_your_token" \
  | jq '.voiceEnabled, .voicePhoneNumber'
```

Then call your phone number. The `firstMessage` should play within 2 seconds of the call connecting.

## Limitations

* Managed mode links one phone number per tenant; with your own Vapi/voice platform (Level 2–3) you can route as many numbers as you like
* Animam does not terminate SIP itself — the telephony/media layer is always your voice orchestrator's responsibility (provisioning, audio quality, latency, fallback)
* Recording storage is managed by Vapi, not Animam
* Voice channel does not support file attachments
* `COLLECT_PAYMENT` (Stripe) is not triggered during voice calls — the agent can describe payment options but cannot generate a checkout link mid-call
