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.
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
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.
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
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:
export PRAISONAI_CALL_AUTH=disabledpraisonai 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:
Without PRAISONAI_CALL_BIND_HOST set to a localhost value, every request is rejected with:
503 Service UnavailablePRAISONAI_CALL_AUTH=disabled is only permitted for localhost binding;set PRAISONAI_CALL_BIND_HOST to 127.0.0.1 when binding locally
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.
When CALL_SERVER_TOKEN is not configured and the environment is not development, the server returns:
503 Service UnavailableCALL_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 UnavailablePRAISONAI_CALL_AUTH=disabled is only permitted for localhost binding;set PRAISONAI_CALL_BIND_HOST to 127.0.0.1 when binding locally
The call server binds to 127.0.0.1 by default, so it is only reachable from the same machine.
# Local development (default — same machine only)praisonai call# Specific port, still localhost-onlypraisonai call --port 8090# Expose on LAN (warning will be printed)praisonai call --host 0.0.0.0 --port 8090# Expose publicly via ngrokexport NGROK_AUTH_TOKEN="${NGROK_AUTH_TOKEN:?Set NGROK_AUTH_TOKEN in your shell}"praisonai call --public
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.
import yfinance as yf# Get Stock Price definitionget_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 / Toolasync 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]
pip install yfinance
4. ```bashexport 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
# Use an official Python runtime as a parent imageFROM python:3.11-slim# Set environment variablesENV PYTHONDONTWRITEBYTECODE 1ENV PYTHONUNBUFFERED 1# Set work directoryWORKDIR /app# Install system dependenciesRUN 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 versionRUN pip install --no-cache-dir --upgrade "praisonai[call]"# Expose the port the app runs onEXPOSE 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"]