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

# PraisonAI Call

> Guide to PraisonAI's voice-based interaction feature enabling AI customer service through phone calls, including setup and tool integration

Turn an Agent into a phone assistant — start the call server and connect a phone number to talk to it over the line.

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
export OPENAI_API_KEY="${OPENAI_API_KEY:?Set OPENAI_API_KEY in your shell}"
export NGROK_AUTH_TOKEN="${NGROK_AUTH_TOKEN:?Set NGROK_AUTH_TOKEN in your shell}"
praisonai call --public
```

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    subgraph "PraisonAI Call"
        Caller[📞 Caller] --> Call[🤖 Call Server]
        Call --> Agent[🧠 Agent]
        Agent --> Voice[✅ Voice Reply]
    end

    classDef input fill:#8B0000,stroke:#7C90A0,color:#fff
    classDef process fill:#189AB4,stroke:#7C90A0,color:#fff
    classDef output fill:#10B981,stroke:#7C90A0,color:#fff

    class Caller,Call input
    class Agent process
    class Voice output
```

<iframe width="560" height="315" src="https://www.youtube.com/embed/m1cwrUG2iAk" title="YouTube video player" frameborder="0" allow="accelerometer; autoplay; clipboard-write; encrypted-media; gyroscope; picture-in-picture" allowfullscreen />

## AI Customer Service

PraisonAI Call is a feature that enables voice-based interaction with AI models through phone calls. This functionality allows users to have natural conversations with AI agents over traditional phone lines.

## Installation

### Step 1

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
pip install "praisonai[call]"
export OPENAI_API_KEY="${OPENAI_API_KEY:?Set OPENAI_API_KEY in your shell}"
export NGROK_AUTH_TOKEN="${NGROK_AUTH_TOKEN:?Set NGROK_AUTH_TOKEN in your shell}"
praisonai call --public
```

### Step 2

Buy a number at [PraisonAI Dashboard](https://dashboard.praison.ai/)

### Step 3

Enter the Public URL in the PraisonAI Dashboard phone number field

## Authentication

<Warning>
  **Breaking Change**: When upgrading from earlier versions, the call server requires authentication configuration or it will fail with a 503 error.
</Warning>

The PraisonAI Call server now requires authentication configuration for security. You have two options:

### Option 1: Token Authentication (Recommended)

Set a secure token for API authentication:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
export CALL_SERVER_TOKEN="${CALL_SERVER_TOKEN:?Set CALL_SERVER_TOKEN in your shell}"
praisonai call --public
```

API requests must include the token in the Authorization header:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
curl -H "Authorization: Bearer ${CALL_SERVER_TOKEN:?Set CALL_SERVER_TOKEN in your shell}" \
     -H "Content-Type: application/json" \
     -d '{"message": "Hello"}' \
     http://localhost:8090/api/v1/agents/assistant/invoke
```

### Option 2: Disable Authentication (Local Development Only)

For local development on your own machine, you can disable authentication. The CLI sets the bind-host env var for you, so this is enough when launching via `praisonai call`:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
export PRAISONAI_CALL_AUTH=disabled
praisonai call
```

If you launch the server programmatically (custom `uvicorn`, embedding `praisonai.api.agent_invoke` in another app, or any path that does NOT go through `praisonai call` / `praisonai serve`), you must also pin the bind host:

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
export PRAISONAI_CALL_AUTH=disabled
export PRAISONAI_CALL_BIND_HOST=127.0.0.1
```

Without `PRAISONAI_CALL_BIND_HOST` set to a localhost value, every request is rejected with:

```
503 Service Unavailable
PRAISONAI_CALL_AUTH=disabled is only permitted for localhost binding;
set PRAISONAI_CALL_BIND_HOST to 127.0.0.1 when binding locally
```

<Warning>
  Never use `PRAISONAI_CALL_AUTH=disabled` in production. It is rejected outright unless the server is bound to localhost, and even then it bypasses all caller verification.
</Warning>

### Authentication Flow

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph LR
    A[📝 Request] --> B{🔐 Has Bearer Token?}
    B -->|Yes| C[✅ 200 Success]
    B -->|No| D{⚙️ Auth Disabled?}
    D -->|Yes| H{🏠 Bind host is localhost?}
    H -->|Yes| C
    H -->|No| G[❌ 503 Service Unavailable]
    D -->|No| E{🔧 Token Configured?}
    E -->|Yes| F[❌ 401 Unauthorized]
    E -->|No| G

    classDef request fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef check fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef success fill:#10B981,stroke:#7C90A0,color:#fff
    classDef error fill:#8B0000,stroke:#7C90A0,color:#fff

    class A request
    class B,D,E,H check
    class C success
    class F,G error
```

When `CALL_SERVER_TOKEN` is not configured and the environment is not development, the server returns:

```
503 Service Unavailable
CALL_SERVER_TOKEN is not configured. Set CALL_SERVER_TOKEN or PRAISONAI_CALL_AUTH=disabled to run without authentication.
```

When `PRAISONAI_CALL_AUTH=disabled` is set but the bind host is not localhost:

```
503 Service Unavailable
PRAISONAI_CALL_AUTH=disabled is only permitted for localhost binding;
set PRAISONAI_CALL_BIND_HOST to 127.0.0.1 when binding locally
```

### Environment Variables

| Env var                        | Required when                                                          | Effect                                                                      |
| ------------------------------ | ---------------------------------------------------------------------- | --------------------------------------------------------------------------- |
| `CALL_SERVER_TOKEN`            | Production / any non-local exposure                                    | Server requires `Authorization: Bearer <token>`                             |
| `PRAISONAI_CALL_AUTH=disabled` | Local development only                                                 | Bypasses auth — **only honored if `PRAISONAI_CALL_BIND_HOST` is localhost** |
| `PRAISONAI_CALL_BIND_HOST`     | Whenever you launch without the `praisonai call`/`praisonai serve` CLI | Declares the real bind host so the auth-disabled guard can verify it        |

## Binding & Network Access

The call server binds to `127.0.0.1` by default, so it is only reachable from the same machine.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
graph TB
    Start([Where will clients connect from?]) --> Local{Same machine only?}
    Local -->|Yes| Localhost["✅ Default<br/>praisonai call"]
    Local -->|No| LAN{Local network?}
    LAN -->|Yes| LANbind["⚠️ praisonai call --host 0.0.0.0<br/>or bind to a specific NIC<br/>--host 192.168.1.x"]
    LAN -->|No| Public["🌐 praisonai call --public<br/>(uses ngrok)"]

    classDef input fill:#6366F1,stroke:#7C90A0,color:#fff
    classDef branch fill:#F59E0B,stroke:#7C90A0,color:#fff
    classDef safe fill:#10B981,stroke:#7C90A0,color:#fff
    classDef warn fill:#8B0000,stroke:#7C90A0,color:#fff

    class Start input
    class Local,LAN branch
    class Localhost,Public safe
    class LANbind warn
```

```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Local development (default — same machine only)
praisonai call

# Specific port, still localhost-only
praisonai call --port 8090

# Expose on LAN (warning will be printed)
praisonai call --host 0.0.0.0 --port 8090

# Expose publicly via ngrok
export NGROK_AUTH_TOKEN="${NGROK_AUTH_TOKEN:?Set NGROK_AUTH_TOKEN in your shell}"
praisonai call --public
```

<Warning>
  **Breaking change (earlier versions → this release):** Earlier versions of `praisonai call` bound to `0.0.0.0` unconditionally, exposing the server to your entire LAN. Starting in this release, the default is `127.0.0.1`. Production deployments that previously relied on the LAN-exposed default must add `--host 0.0.0.0` (or a specific NIC) and ensure `CALL_SERVER_TOKEN` is set.
</Warning>

## Features

* Make and receive phone calls with AI agents
* Natural language processing for voice interactions
* Support for multiple phone carriers and providers
* Call recording and transcription capabilities
* Integration with other PraisonAI features

## Adding Tools

1. Create a file called `tools.py`
2. Add the following code:

```python theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
import yfinance as yf

# Get Stock Price definition
get_stock_price_def = {
    "name": "get_stock_price",
    "description": "Get the current stock price for a given ticker symbol",
    "parameters": {
        "type": "object", 
        "properties": {
            "ticker_symbol": {
                "type": "string", 
                "description": "The ticker symbol of the stock (e.g., AAPL, GOOGL)"
            }
        }, 
        "required": ["ticker_symbol"]
    }
}

# Get Stock Price function / Tool
async def get_stock_price_handler(ticker_symbol):
    try:
        stock = yf.Ticker(ticker_symbol)
        hist = stock.history(period="1d")
        if hist.empty:
            return {"error": f"No data found for ticker {ticker_symbol}"}
        current_price = hist['Close'].iloc[-1]  # Using -1 is safer than 0
        return {"price": str(current_price)}
    except Exception as e:
        return {"error": str(e)}



get_stock_price = (get_stock_price_def, get_stock_price_handler)
tools = [
    get_stock_price
]
```

3. ```bash theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
   ```

pip install yfinance

````

4. ```bash
export OPENAI_API_KEY="${OPENAI_API_KEY:?Set OPENAI_API_KEY in your shell}"
export NGROK_AUTH_TOKEN="${NGROK_AUTH_TOKEN:?Set NGROK_AUTH_TOKEN in your shell}"
praisonai call --public
````

## Manage Google Calendar Events

See [Google Calendar Tools](tools/googlecalendar.md)

## Deploy

### Docker Deployment

```dockerfile theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
# Use an official Python runtime as a parent image
FROM python:3.11-slim

# Set environment variables
ENV PYTHONDONTWRITEBYTECODE 1
ENV PYTHONUNBUFFERED 1

# Set work directory
WORKDIR /app

# Install system dependencies
RUN apt-get update && apt-get install -y --no-install-recommends \
    build-essential \
    && rm -rf /var/lib/apt/lists/*

# Install PraisonAI with the 'call' extra and ensure it's the latest version
RUN pip install --no-cache-dir --upgrade "praisonai[call]"

# Expose the port the app runs on
EXPOSE 8090

# Bind to all container interfaces — the container boundary is the security boundary.
# Pair with CALL_SERVER_TOKEN for any externally-published port.
CMD ["praisonai", "call", "--host", "0.0.0.0"]
```

## How It Works

A caller dials your number, the provider forwards audio to the call server, and the Agent responds with synthesized speech.

```mermaid theme={"theme":{"light":"vitesse-light","dark":"vitesse-dark"}}
sequenceDiagram
    participant Caller
    participant Call as Call Server
    participant Agent

    Caller->>Call: Phone call audio
    Call->>Agent: Transcribed request
    Agent-->>Call: Response text
    Call-->>Caller: Synthesized voice reply
```

## Best Practices

<AccordionGroup>
  <Accordion title="Always set CALL_SERVER_TOKEN in production">
    The server fails with 503 unless a token is set or auth is explicitly disabled for localhost. Never disable auth on a public bind.
  </Accordion>

  <Accordion title="Keep the default localhost bind">
    `praisonai call` binds to `127.0.0.1` by default. Add `--host 0.0.0.0` only inside a container or when you deliberately expose the LAN.
  </Accordion>

  <Accordion title="Set secrets via environment variables">
    Export `OPENAI_API_KEY`, `NGROK_AUTH_TOKEN`, and `CALL_SERVER_TOKEN` in your shell — never inline the raw values.
  </Accordion>

  <Accordion title="Add tools for real actions">
    Register async tool handlers (like a stock-price lookup) so the phone agent can fetch live data during a call.
  </Accordion>
</AccordionGroup>

## Related

<CardGroup cols={2}>
  <Card title="Tools" icon="wrench" href="/docs/tools">
    Give your call agent live data and actions.
  </Card>

  <Card title="Security" icon="shield" href="/docs/security">
    Harden the call server before exposing it.
  </Card>
</CardGroup>
