This guide covers setting up phone numbers, deploying your agent to production, and managing calls.
- Dashboard Setup
- Phone Number Configuration
- Agent Deployment
- Call Routing
- Monitoring & Analytics
- Production Best Practices
- Go to dashboard.piopiy.com
- Sign up with your email
- Verify your email address
- Complete your profile
- Navigate to Voice AI Agents in the dashboard
- Click Create Agent
- Fill in agent details:
- Name: Descriptive name (e.g., "Customer Support Agent")
- Description: Purpose of the agent
- Click Create
- Copy your credentials:
AGENT_ID: Unique identifierAGENT_TOKEN: Authentication token
AGENT_TOKEN secure! Never commit it to version control.
- Go to Phone Numbers in the dashboard
- Click Buy Number
- Select your country and area code
- Choose a number from available options
- Complete the purchase
- Go to Phone Numbers
- Click on your purchased number
- Under Configuration, select:
- Type: Voice AI Agent
- Agent: Select your agent from dropdown
- Click Save
Now calls to this number will route to your agent!
Run your agent locally for testing:
# Set environment variables
export AGENT_ID=your_agent_id
export AGENT_TOKEN=your_agent_token
export OPENAI_API_KEY=your_openai_key
export DEEPGRAM_API_KEY=your_deepgram_key
export CARTESIA_API_KEY=your_cartesia_key
# Run agent
python my_agent.pyDeploy to a cloud server (AWS, GCP, Azure, DigitalOcean):
1. Prepare your server:
# Install Python 3.10+
sudo apt update
sudo apt install python3.10 python3-pip
# Clone your agent code
git clone https://github.com/your-repo/your-agent.git
cd your-agent
# Install dependencies
pip install -r requirements.txt2. Set environment variables:
# Create .env file
cat > .env << EOF
AGENT_ID=your_agent_id
AGENT_TOKEN=your_agent_token
OPENAI_API_KEY=your_openai_key
DEEPGRAM_API_KEY=your_deepgram_key
CARTESIA_API_KEY=your_cartesia_key
AGENT_DEBUG=false
EOF3. Run as a service (systemd):
# Create service file
sudo nano /etc/systemd/system/piopiy-agent.service[Unit]
Description=Piopiy Voice AI Agent
After=network.target
[Service]
Type=simple
User=ubuntu
WorkingDirectory=/home/ubuntu/your-agent
Environment="PATH=/home/ubuntu/.local/bin:/usr/bin"
EnvironmentFile=/home/ubuntu/your-agent/.env
ExecStart=/usr/bin/python3 my_agent.py
Restart=always
RestartSec=10
[Install]
WantedBy=multi-user.target# Enable and start service
sudo systemctl daemon-reload
sudo systemctl enable piopiy-agent
sudo systemctl start piopiy-agent
# Check status
sudo systemctl status piopiy-agent
# View logs
sudo journalctl -u piopiy-agent -fDockerfile:
FROM python:3.10-slim
WORKDIR /app
COPY requirements.txt .
RUN pip install --no-cache-dir -r requirements.txt
COPY . .
CMD ["python", "my_agent.py"]docker-compose.yml:
version: '3.8'
services:
agent:
build: .
env_file:
- .env
restart: unless-stopped
logging:
driver: "json-file"
options:
max-size: "10m"
max-file: "3"Deploy:
# Build and run
docker-compose up -d
# View logs
docker-compose logs -f
# Stop
docker-compose downdeployment.yaml:
apiVersion: apps/v1
kind: Deployment
metadata:
name: piopiy-agent
spec:
replicas: 3
selector:
matchLabels:
app: piopiy-agent
template:
metadata:
labels:
app: piopiy-agent
spec:
containers:
- name: agent
image: your-registry/piopiy-agent:latest
env:
- name: AGENT_ID
valueFrom:
secretKeyRef:
name: piopiy-secrets
key: agent-id
- name: AGENT_TOKEN
valueFrom:
secretKeyRef:
name: piopiy-secrets
key: agent-token
resources:
requests:
memory: "256Mi"
cpu: "250m"
limits:
memory: "512Mi"
cpu: "500m"All calls to your assigned number route to your agent automatically.
Pass custom data to your agent based on call source:
1. Via Dashboard:
When creating a test call, add metadata in JSON format:
{
"customer_id": "CUST_1001",
"campaign": "summer_sale",
"priority": 5
}2. Via API:
curl -X POST https://api.piopiy.com/v1/calls \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+1234567890",
"agent_id": "your_agent_id",
"metadata": {
"customer_id": "CUST_1001",
"source": "website"
}
}'3. Handle in your agent:
async def create_session(call_id, metadata=None, **kwargs):
if metadata:
customer_id = metadata.get("customer_id")
priority = metadata.get("priority", 1)
# Route to specialized agent
if priority > 5:
voice_agent = VoiceAgent(
instructions="You are a priority support agent...",
greeting="Hello valued customer!"
)
else:
voice_agent = VoiceAgent(
instructions="You are a support agent...",
greeting="Hello! How can I help?"
)View call history in the dashboard:
- Go to Call Logs
- Filter by:
- Date range
- Agent
- Phone number
- Call status
Click on any call to see:
- Duration
- Caller/Called numbers
- Metadata
- Recording (if enabled)
- Transcription
Monitor your agent's logs:
import logging
# Configure logging
logging.basicConfig(
level=logging.INFO,
format='%(asctime)s - %(name)s - %(levelname)s - %(message)s',
handlers=[
logging.FileHandler('agent.log'),
logging.StreamHandler()
]
)
async def create_session(call_id, **kwargs):
logging.info(f"Call started: {call_id}")
try:
# Agent logic
await voice_agent.start()
logging.info(f"Call completed: {call_id}")
except Exception as e:
logging.error(f"Call failed: {call_id}, Error: {e}")- Call Volume: Total calls per day/hour
- Call Duration: Average call length
- Success Rate: Completed vs failed calls
- Response Time: Time to first response
- Provider Costs: Track API usage
Run multiple agent instances:
# Use process manager (PM2, systemd, etc.)
# Or container orchestration (Kubernetes, ECS)Implement comprehensive error handling:
async def create_session(call_id, **kwargs):
try:
voice_agent = VoiceAgent(...)
await voice_agent.start()
except Exception as e:
logging.error(f"Call {call_id} error: {e}")
# Send alert to monitoring service
# Play fallback message to callerProtect against API rate limits:
import asyncio
from collections import deque
from time import time
class RateLimiter:
def __init__(self, max_calls, period):
self.max_calls = max_calls
self.period = period
self.calls = deque()
async def acquire(self):
now = time()
while self.calls and self.calls[0] < now - self.period:
self.calls.popleft()
if len(self.calls) >= self.max_calls:
sleep_time = self.period - (now - self.calls[0])
await asyncio.sleep(sleep_time)
self.calls.append(time())
# Use in agent
limiter = RateLimiter(max_calls=10, period=60) # 10 calls per minute
async def create_session(call_id, **kwargs):
await limiter.acquire()
# Proceed with callNever hardcode secrets:
# β Bad
api_key = "sk-1234567890"
# β
Good
import os
api_key = os.getenv("OPENAI_API_KEY")
# β
Better (use secret manager)
from aws_secretsmanager import get_secret
api_key = get_secret("openai_api_key")Implement health check endpoint:
from aiohttp import web
async def health_check(request):
return web.json_response({"status": "healthy"})
app = web.Application()
app.router.add_get('/health', health_check)
# Run alongside your agent
web.run_app(app, port=8080)Handle shutdown signals:
import signal
import asyncio
async def shutdown(agent):
print("Shutting down gracefully...")
await agent.shutdown()
print("Shutdown complete")
async def main():
agent = Agent(...)
# Register signal handlers
loop = asyncio.get_running_loop()
for sig in (signal.SIGTERM, signal.SIGINT):
loop.add_signal_handler(
sig,
lambda: asyncio.create_task(shutdown(agent))
)
await agent.connect()Monitor and optimize costs:
# Use cost-effective models
llm = OpenAILLMService(model="gpt-4o-mini") # Cheaper than GPT-4
# Cache common responses
from functools import lru_cache
@lru_cache(maxsize=100)
def get_faq_response(question):
# Return cached response for common questions
pass
# Implement timeout for long calls
async def create_session(call_id, **kwargs):
try:
await asyncio.wait_for(voice_agent.start(), timeout=300) # 5 min max
except asyncio.TimeoutError:
logging.warning(f"Call {call_id} exceeded timeout")- Verify agent is running:
systemctl status piopiy-agent - Check network connectivity
- Verify
AGENT_IDandAGENT_TOKENare correct - Check dashboard for agent status
- Check internet bandwidth (minimum 1 Mbps)
- Reduce latency by choosing nearby providers
- Enable
debug=Trueto identify bottlenecks
- Use cost-effective models (GPT-4o-mini vs GPT-4)
- Implement caching for common responses
- Set max call duration limits
- Monitor provider usage in dashboards
- Developer Guide - Advanced features
- API Reference - Complete API docs
- Examples - Code examples
- Email: support@piopiy.com
- Dashboard: dashboard.piopiy.com