Quick Start
Get started with the VaniAgent API in minutes. This guide will walk you through making your first API call to create an AI voice agent.
1. Get Your API Key
Sign up for a VaniAgent account and generate your API key from the dashboard.
2. Make Your First API Call
Use your API key to create an AI voice agent. Here's a simple example using cURL:
#18b8b2]">"text-[#2b7bb9]">curl "text-[#f4a83b]">-X POST https://api.vaniagent.com/v1/agents \
#18b8b2]">"text-[#f4a83b]">-H "Authorization: Bearer YOUR_API_KEY" \
#18b8b2]">"text-[#f4a83b]">-H "Content">-Type: application/json" \
#18b8b2]">"text-[#f4a83b]">-d '{
#18b8b2]">"name": "Customer Support Agent",
#18b8b2]">"voice": "en">-US">-Neural2">-F",
#18b8b2]">"prompt": "You are a helpful customer support agent."
}'3. Start Making Calls
Once your agent is created, you can start making calls:
#18b8b2]">"text-[#2b7bb9]">curl "text-[#f4a83b]">-X POST https://api.vaniagent.com/v1/calls \
#18b8b2]">"text-[#f4a83b]">-H "Authorization: Bearer YOUR_API_KEY" \
#18b8b2]">"text-[#f4a83b]">-H "Content">-Type: application/json" \
#18b8b2]">"text-[#f4a83b]">-d '{
#18b8b2]">"agent_id": "agent_123",
#18b8b2]">"to_number": "+1234567890",
#18b8b2]">"from_number": "+0987654321"
}'Authentication
The VaniAgent API uses API keys to authenticate requests. You can view and manage your API keys in the VaniAgent Dashboard.
Keep your API keys secure
Your API keys carry many privileges, so be sure to keep them secure! Do not share your secret API keys in publicly accessible areas such as GitHub, client-side code, etc.
Bearer Token Authentication
All API requests must include your API key in the Authorization header:
Authorization: Bearer YOUR_API_KEYExample Request
"text-[#2b7bb9]">const response = "text-[#2b7bb9]">await fetch('https://api.vaniagent.com/v1/agents', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
name: 'Support Agent',
voice: 'en-US-Neural2-F'
})
});
"text-[#2b7bb9]">const data = "text-[#2b7bb9]">await response.json();
console.log(data);REST API Reference
The VaniAgent REST API provides endpoints for managing agents, making calls, and retrieving call data. All endpoints use JSON for request and response bodies.
/v1/agentsCreate Agent
Create a new AI voice agent with custom configuration.
Request Body
{
"name": "Customer Support Agent",
"voice": "en-US-Neural2-F",
"prompt": "You are a helpful customer support agent.",
"language": "en-US",
"temperature": 0.7,
"max_duration": 600
}Response
{
"id": "agent_abc123",
"name": "Customer Support Agent",
"voice": "en-US-Neural2-F",
"status": "active",
"created_at": "2024-01-15T10: 30: 00Z"
}/v1/callsMake Call
Initiate an outbound call using a configured agent.
Request Body
{
"agent_id": "agent_abc123",
"to_number": "+1234567890",
"from_number": "+0987654321",
"metadata": {
"customer_id": "cust_123",
"campaign": "support_followup"
}
}Response
{
"id": "call_xyz789",
"agent_id": "agent_abc123",
"status": "initiated",
"to_number": "+1234567890",
"from_number": "+0987654321",
"created_at": "2024-01-15T10: 35: 00Z"
}/v1/calls/:call_idGet Call Status
Retrieve detailed information about a specific call.
Response
{
"id": "call_xyz789",
"agent_id": "agent_abc123",
"status": "completed",
"duration": 245,
"transcript": "...",
"recording_url": "https://...",
"sentiment": "positive",
"created_at": "2024-01-15T10: 35: 00Z",
"completed_at": "2024-01-15T10: 39: 05Z"
}/v1/callsList Calls
Retrieve a paginated list of all calls.
Query Parameters
limit- Number of results (default: 20, max: 100)offset- Pagination offsetagent_id- Filter by agent IDstatus- Filter by status (initiated, in_progress, completed, failed)
Response
{
"data": [
{
"id": "call_xyz789",
"agent_id": "agent_abc123",
"status": "completed",
"duration": 245,
"created_at": "2024-01-15T10: 35: 00Z"
}
],
"total": 150,
"limit": 20,
"offset": 0
}WebSocket API
The WebSocket API provides real-time bidirectional communication for live call monitoring, streaming transcripts, and interactive voice applications.
Connection Setup
Connect to the WebSocket endpoint with your API key:
"text-[#2b7bb9]">const ws = "text-[#2b7bb9]">new WebSocket('wss://api.vaniagent.com/v1/ws');
ws.onopen = () => {
// Authenticate
ws.send(JSON.stringify({
type: 'auth',
api_key: 'YOUR_API_KEY'
}));
// Subscribe to call events
ws.send(JSON.stringify({
type: 'subscribe',
call_id: 'call_xyz789'
}));
};
ws.onmessage = (event) => {
"text-[#2b7bb9]">const data = JSON.parse(event.data);
console.log('Received:', data);
};Real-Time Events
Receive real-time updates during calls:
// Call Started
{
"type": "call.started",
"call_id": "call_xyz789",
"timestamp": "2024-01-15T10: 35: 00Z"
}
// Transcript Update (streaming)
{
"type": "transcript.update",
"call_id": "call_xyz789",
"speaker": "agent",
"text": "Hello, how can I help you today?",
"is_final": true,
"timestamp": "2024-01-15T10: 35: 02Z"
}
// Call Completed
{
"type": "call.completed",
"call_id": "call_xyz789",
"duration": 245,
"timestamp": "2024-01-15T10: 39: 05Z"
}Python Example
#18b8b2]">"text-[#2b7bb9]">import asyncio
#18b8b2]">"text-[#2b7bb9]">import websockets
#18b8b2]">"text-[#2b7bb9]">import json
#18b8b2]">"text-[#2b7bb9]">async "text-[#2b7bb9]">def connect():
uri = #18b8b2]">"wss://api.vaniagent.com/v1/ws"
#18b8b2]">"text-[#2b7bb9]">async "text-[#2b7bb9]">with websockets.connect(uri) "text-[#2b7bb9]">as websocket:
# Authenticate
#18b8b2]">"text-[#2b7bb9]">await websocket.send(json.dumps({
#18b8b2]">"type": "auth",
#18b8b2]">"api_key": "YOUR_API_KEY"
}))
# Subscribe to call
#18b8b2]">"text-[#2b7bb9]">await websocket.send(json.dumps({
#18b8b2]">"type": "subscribe",
#18b8b2]">"call_id": "call_xyz789"
}))
# Listen "text-[#2b7bb9]">for events
#18b8b2]">"text-[#2b7bb9]">async "text-[#2b7bb9]">for message in websocket:
data = json.loads(message)
print(f#18b8b2]">"Received: {data}")
asyncio.run(connect())Webhooks
Webhooks allow you to receive real-time notifications about events in your VaniAgent account. Configure webhook endpoints in your dashboard to receive POST requests when events occur.
Webhook Setup
Configure your webhook endpoint to receive events:
- Go to Dashboard → Settings → Webhooks
- Add your endpoint URL (must be HTTPS)
- Select which events to receive
- Save your webhook secret for signature verification
Event Types
call.started- Call has been initiatedcall.completed- Call has ended successfullycall.failed- Call failed to completetranscript.ready- Full transcript is availablerecording.ready- Call recording is available
Webhook Payload
{
"event": "call.completed",
"timestamp": "2024-01-15T10: 39: 05Z",
"data": {
"call_id": "call_xyz789",
"agent_id": "agent_abc123",
"duration": 245,
"status": "completed",
"transcript_url": "https://...",
"recording_url": "https://...",
"metadata": {
"customer_id": "cust_123"
}
}
}Signature Verification
Verify webhook signatures to ensure requests are from VaniAgent:
"text-[#2b7bb9]">const crypto = require('crypto');
"text-[#2b7bb9]">function verifyWebhook(payload, signature, secret) {
"text-[#2b7bb9]">const hmac = crypto.createHmac('sha256', secret);
"text-[#2b7bb9]">const digest = hmac.update(payload).digest('hex');
"text-[#2b7bb9]">return crypto.timingSafeEqual(
Buffer."text-[#2b7bb9]">from(signature),
Buffer."text-[#2b7bb9]">from(digest)
);
}
// Express.js example
app.post('/webhook', (req, res) => {
"text-[#2b7bb9]">const signature = req.headers['x-vaniagent-signature'];
"text-[#2b7bb9]">const payload = JSON.stringify(req.body);
"text-[#2b7bb9]">if (!verifyWebhook(payload, signature, WEBHOOK_SECRET)) {
"text-[#2b7bb9]">return res.status(401).send('Invalid signature');
}
// Process webhook
console.log('Event:', req.body.event);
res.status(200).send('OK');
});#18b8b2]">"text-[#2b7bb9]">import hmac
#18b8b2]">"text-[#2b7bb9]">import hashlib
#18b8b2]">"text-[#2b7bb9]">def verify_webhook(payload, signature, secret):
digest = hmac.new(
secret.encode(),
payload.encode(),
hashlib.sha256
).hexdigest()
#18b8b2]">"text-[#2b7bb9]">return hmac.compare_digest(signature, digest)
# Flask example
@app.route(#18b8b2]">'/webhook', methods=['POST'])
#18b8b2]">"text-[#2b7bb9]">def webhook():
signature = request.headers.get(#18b8b2]">'X-Vaniagent-Signature')
payload = request.get_data(as_text=True)
#18b8b2]">"text-[#2b7bb9]">if not verify_webhook(payload, signature, WEBHOOK_SECRET):
#18b8b2]">"text-[#2b7bb9]">return 'Invalid signature', 401
# Process webhook
data = request.json
print(f#18b8b2]">"Event: {data['event']}")
#18b8b2]">"text-[#2b7bb9]">return 'OK', 200Error Handling
The VaniAgent API uses conventional HTTP response codes to indicate the success or failure of requests. Codes in the 2xx range indicate success, 4xx indicate client errors, and 5xx indicate server errors.
HTTP Status Codes
200OK
Request succeeded
201Created
Resource created successfully
400Bad Request
Invalid request parameters
401Unauthorized
Invalid or missing API key
404Not Found
Resource does not exist
429Too Many Requests
Rate limit exceeded
500Internal Server Error
Something went wrong on our end
Error Response Format
All errors return a consistent JSON structure:
{
"error": {
"code": "invalid_request",
"message": "The 'to_number' field is required",
"param": "to_number",
"type": "validation_error"
}
}Error Codes
invalid_request- Request parameters are invalidauthentication_failed- API key is invalid or missingresource_not_found- Requested resource doesn't existrate_limit_exceeded- Too many requestsinsufficient_credits- Account has insufficient creditsinternal_error- Server error occurred
Error Handling Example
"text-[#2b7bb9]">async "text-[#2b7bb9]">function makeCall(agentId, toNumber) {
"text-[#2b7bb9]">try {
"text-[#2b7bb9]">const response = "text-[#2b7bb9]">await fetch('https://api.vaniagent.com/v1/calls', {
method: 'POST',
headers: {
'Authorization': 'Bearer YOUR_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
agent_id: agentId,
to_number: toNumber,
from_number: '+0987654321'
})
});
"text-[#2b7bb9]">if (!response.ok) {
"text-[#2b7bb9]">const error = "text-[#2b7bb9]">await response.json();
"text-[#2b7bb9]">throw "text-[#2b7bb9]">new Error(`API Error: ${error.error.message}`);
}
"text-[#2b7bb9]">const data = "text-[#2b7bb9]">await response.json();
"text-[#2b7bb9]">return data;
} "text-[#2b7bb9]">catch (error) {
console.error('Failed to make call:', error.message);
"text-[#2b7bb9]">throw error;
}
}#18b8b2]">"text-[#2b7bb9]">import requests
#18b8b2]">"text-[#2b7bb9]">def make_call(agent_id, to_number):
#18b8b2]">"text-[#2b7bb9]">try:
response = requests.post(
#18b8b2]">'https://api.vaniagent.com/v1/calls',
headers={
#18b8b2]">'Authorization': 'Bearer YOUR_API_KEY',
#18b8b2]">'Content-Type': 'application/json'
},
json={
#18b8b2]">'agent_id': agent_id,
#18b8b2]">'to_number': to_number,
#18b8b2]">'from_number': '+0987654321'
}
)
response.raise_for_status()
#18b8b2]">"text-[#2b7bb9]">return response.json()
#18b8b2]">"text-[#2b7bb9]">except requests.exceptions.HTTPError "text-[#2b7bb9]">as e:
error = e.response.json()
print(f#18b8b2]">"API Error: {error['error']['message']}")
raise
#18b8b2]">"text-[#2b7bb9]">except Exception "text-[#2b7bb9]">as e:
print(f#18b8b2]">"Failed to make call: {str(e)}")
raiseRate Limits
The VaniAgent API implements rate limiting to ensure fair usage and system stability. Rate limits vary by plan tier and endpoint.
Rate Limit Tiers
Starter Plan
100 requests per minute
1,000 requests per hour
Professional Plan
500 requests per minute
10,000 requests per hour
Enterprise Plan
Custom rate limits
Contact sales for details
Rate Limit Headers
Every API response includes headers with rate limit information:
X#18b8b2]">"text-[#f4a83b]">-RateLimit"text-[#f4a83b]">-Limit: 100
X#18b8b2]">"text-[#f4a83b]">-RateLimit"text-[#f4a83b]">-Remaining: 95
X#18b8b2]">"text-[#f4a83b]">-RateLimit"text-[#f4a83b]">-Reset: 1705320000X-RateLimit-Limit- Maximum requests allowed in the current windowX-RateLimit-Remaining- Requests remaining in the current windowX-RateLimit-Reset- Unix timestamp when the rate limit resets
Handling Rate Limits
When you exceed the rate limit, you'll receive a 429 status code. Implement exponential backoff:
"text-[#2b7bb9]">async "text-[#2b7bb9]">function makeRequestWithRetry(url, options, maxRetries = 3) {
"text-[#2b7bb9]">for ("text-[#2b7bb9]">let i = 0; i < maxRetries; i++) {
"text-[#2b7bb9]">try {
"text-[#2b7bb9]">const response = "text-[#2b7bb9]">await fetch(url, options);
"text-[#2b7bb9]">if (response.status === 429) {
"text-[#2b7bb9]">const resetTime = response.headers.get('X-RateLimit-Reset');
"text-[#2b7bb9]">const waitTime = Math.max(
(resetTime * 1000) - Date.now(),
Math.pow(2, i) * 1000
);
console.log(`Rate limited. Waiting ${waitTime}ms...`);
"text-[#2b7bb9]">await "text-[#2b7bb9]">new Promise(resolve => setTimeout(resolve, waitTime));
continue;
}
"text-[#2b7bb9]">return response;
} "text-[#2b7bb9]">catch (error) {
"text-[#2b7bb9]">if (i === maxRetries - 1) "text-[#2b7bb9]">throw error;
}
}
}Best Practices
- • Monitor rate limit headers in your responses
- • Implement exponential backoff for retries
- • Cache responses when possible to reduce API calls
- • Use webhooks instead of polling for real-time updates
- • Contact support if you need higher rate limits
SDKs & Libraries
Official SDKs and code examples to help you integrate VaniAgent into your applications quickly.
JavaScript / Node.js
Official Node.js SDK with TypeScript support
#18b8b2]">"text-[#2b7bb9]">npm install @vaniagent/sdkPython
Official Python SDK for Python 3.7+
pip install vaniagentJavaScript SDK Example
"text-[#2b7bb9]">import { VaniAgent } "text-[#2b7bb9]">from '@vaniagent/sdk';
"text-[#2b7bb9]">const client = "text-[#2b7bb9]">new VaniAgent({
apiKey: 'YOUR_API_KEY'
});
// Create an agent
"text-[#2b7bb9]">const agent = "text-[#2b7bb9]">await client.agents.create({
name: 'Support Agent',
voice: 'en-US-Neural2-F',
prompt: 'You are a helpful customer support agent.'
});
// Make a call
"text-[#2b7bb9]">const call = "text-[#2b7bb9]">await client.calls.create({
agentId: agent.id,
toNumber: '+1234567890',
fromNumber: '+0987654321'
});
// Get call status
"text-[#2b7bb9]">const status = "text-[#2b7bb9]">await client.calls.get(call.id);
console.log('Call status:', status);
// List all calls
"text-[#2b7bb9]">const calls = "text-[#2b7bb9]">await client.calls.list({
limit: 20,
status: 'completed'
});Python SDK Example
#18b8b2]">"text-[#2b7bb9]">from vaniagent "text-[#2b7bb9]">import VaniAgent
client = VaniAgent(api_key=#18b8b2]">'YOUR_API_KEY')
# Create an agent
agent = client.agents.create(
name=#18b8b2]">'Support Agent',
voice=#18b8b2]">'en-US-Neural2-F',
prompt=#18b8b2]">'You are a helpful customer support agent.'
)
# Make a call
call = client.calls.create(
agent_id=agent.id,
to_number=#18b8b2]">'+1234567890',
from_number=#18b8b2]">'+0987654321'
)
# Get call status
status = client.calls.get(call.id)
print(f#18b8b2]">'Call status: {status.status}')
# List all calls
calls = client.calls.list(
limit=20,
status=#18b8b2]">'completed'
)
#18b8b2]">"text-[#2b7bb9]">for call in calls:
print(f#18b8b2]">'Call {call.id}: {call.duration}s')cURL Examples
Quick examples using cURL for testing:
# Create an agent
#18b8b2]">"text-[#2b7bb9]">curl "text-[#f4a83b]">-X POST https://api.vaniagent.com/v1/agents \
#18b8b2]">"text-[#f4a83b]">-H "Authorization: Bearer YOUR_API_KEY" \
#18b8b2]">"text-[#f4a83b]">-H "Content">-Type: application/json" \
#18b8b2]">"text-[#f4a83b]">-d '{
#18b8b2]">"name": "Support Agent",
#18b8b2]">"voice": "en">-US">-Neural2">-F",
#18b8b2]">"prompt": "You are a helpful customer support agent."
}'
# Make a call
#18b8b2]">"text-[#2b7bb9]">curl "text-[#f4a83b]">-X POST https://api.vaniagent.com/v1/calls \
#18b8b2]">"text-[#f4a83b]">-H "Authorization: Bearer YOUR_API_KEY" \
#18b8b2]">"text-[#f4a83b]">-H "Content">-Type: application/json" \
#18b8b2]">"text-[#f4a83b]">-d '{
#18b8b2]">"agent_id": "agent_abc123",
#18b8b2]">"to_number": "+1234567890",
#18b8b2]">"from_number": "+0987654321"
}'
# Get call status
#18b8b2]">"text-[#2b7bb9]">curl "text-[#f4a83b]">-X GET https://api.vaniagent.com/v1/calls/call_xyz789 \
#18b8b2]">"text-[#f4a83b]">-H "Authorization: Bearer YOUR_API_KEY"
# List calls
#18b8b2]">"text-[#2b7bb9]">curl "text-[#f4a83b]">-X GET "https://api.vaniagent.com/v1/calls?limit=20&status=completed" \
#18b8b2]">"text-[#f4a83b]">-H "Authorization: Bearer YOUR_API_KEY"