REST API Reference
The Edesy Voice Agent API enables you to manage agents, initiate calls, and retrieve call data programmatically.
Base URL
https://api.edesy.in/v1
Authentication
All API requests require authentication using a Bearer token:
curl https://api.edesy.in/v1/agents \
-H "Authorization: Bearer YOUR_API_KEY"
Getting an API Key
- Log in to the Edesy Dashboard
- Navigate to Settings → API Keys
- Create a new API key
Agents
List Agents
GET /agents
Response:
{
"data": [
{
"id": "agent_abc123",
"name": "Customer Support",
"language": "en-US",
"llmProvider": "gemini-2.5",
"sttProvider": "deepgram",
"ttsProvider": "cartesia",
"status": "active",
"createdAt": "2024-12-01T10:00:00Z",
"updatedAt": "2024-12-28T15:30:00Z"
}
],
"pagination": {
"total": 10,
"page": 1,
"pageSize": 20
}
}
Create Agent
POST /agents
Request Body:
{
"name": "Customer Support",
"language": "en-US",
"llmProvider": "gemini-2.5",
"llmModel": "gemini-2.5-flash-lite",
"llmTemperature": 0.7,
"sttProvider": "deepgram",
"sttModel": "nova-3",
"ttsProvider": "cartesia",
"ttsVoice": "95856005-0332-41b0-935f-352e296aa0df",
"prompt": "You are a helpful customer support agent...",
"greetingMessage": "Hello! How can I help you today?",
"allowInterruptions": true,
"tools": [
{
"type": "function",
"function": {
"name": "get_order_status",
"description": "Get order status by ID",
"parameters": {
"type": "object",
"properties": {
"order_id": {"type": "string"}
},
"required": ["order_id"]
}
}
}
]
}
Response:
{
"id": "agent_xyz789",
"name": "Customer Support",
"status": "active",
"createdAt": "2024-12-28T16:00:00Z"
}
Get Agent
GET /agents/{agent_id}
Response:
{
"id": "agent_abc123",
"name": "Customer Support",
"language": "en-US",
"llmProvider": "gemini-2.5",
"llmModel": "gemini-2.5-flash-lite",
"llmTemperature": 0.7,
"sttProvider": "deepgram",
"sttModel": "nova-3",
"ttsProvider": "cartesia",
"ttsVoice": "95856005-0332-41b0-935f-352e296aa0df",
"prompt": "You are a helpful customer support agent...",
"greetingMessage": "Hello! How can I help you today?",
"allowInterruptions": true,
"tools": [...],
"webhooks": {
"url": "https://example.com/webhook",
"events": ["call.ended"]
},
"stats": {
"totalCalls": 1250,
"avgDuration": 180,
"avgLatency": 420
},
"createdAt": "2024-12-01T10:00:00Z",
"updatedAt": "2024-12-28T15:30:00Z"
}
Update Agent
PATCH /agents/{agent_id}
Request Body:
{
"prompt": "Updated system prompt...",
"llmTemperature": 0.8
}
Delete Agent
DELETE /agents/{agent_id}
Calls
Initiate Outbound Call
POST /calls
Request Body:
{
"agentId": "agent_abc123",
"to": "+14155551234",
"from": "+14155559876",
"metadata": {
"campaign_id": "summer_promo",
"customer_id": "cust_123"
},
"variables": {
"customer_name": "John",
"order_id": "ORD-12345"
}
}
Response:
{
"id": "call_def456",
"status": "initiated",
"direction": "outbound",
"to": "+14155551234",
"from": "+14155559876",
"agentId": "agent_abc123",
"createdAt": "2024-12-28T16:30:00Z"
}
Get Call
GET /calls/{call_id}
Response:
{
"id": "call_def456",
"agentId": "agent_abc123",
"direction": "outbound",
"status": "completed",
"to": "+14155551234",
"from": "+14155559876",
"startedAt": "2024-12-28T16:30:00Z",
"endedAt": "2024-12-28T16:35:00Z",
"duration": 300,
"endReason": "user_hangup",
"metrics": {
"turnCount": 12,
"avgResponseTime": 450,
"interruptions": 2
},
"recording": {
"id": "rec_ghi789",
"url": "https://storage.edesy.in/recordings/call_def456.mp3",
"duration": 300
},
"transcript": {
"id": "trans_jkl012",
"url": "https://api.edesy.in/v1/transcripts/trans_jkl012"
}
}
List Calls
GET /calls
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
agentId |
string | Filter by agent |
status |
string | Filter by status |
from |
datetime | Start date |
to |
datetime | End date |
page |
integer | Page number |
pageSize |
integer | Items per page |
Response:
{
"data": [
{
"id": "call_def456",
"agentId": "agent_abc123",
"direction": "outbound",
"status": "completed",
"duration": 300,
"createdAt": "2024-12-28T16:30:00Z"
}
],
"pagination": {
"total": 100,
"page": 1,
"pageSize": 20
}
}
End Call
POST /calls/{call_id}/end
Request Body:
{
"reason": "manual_termination"
}
Transcripts
Get Transcript
GET /transcripts/{transcript_id}
Response:
{
"id": "trans_jkl012",
"callId": "call_def456",
"turns": [
{
"id": "turn_1",
"role": "assistant",
"text": "Hello! How can I help you today?",
"timestamp": 0
},
{
"id": "turn_2",
"role": "user",
"text": "What's the status of my order?",
"timestamp": 2500,
"confidence": 0.95
},
{
"id": "turn_3",
"role": "assistant",
"text": "I'd be happy to help. What's your order number?",
"timestamp": 3200
}
],
"summary": "Customer inquired about order status. Agent provided tracking information.",
"topics": ["order_status"],
"sentiment": "neutral"
}
Recordings
Get Recording
GET /recordings/{recording_id}
Response:
{
"id": "rec_ghi789",
"callId": "call_def456",
"duration": 300,
"format": "mp3",
"channels": "dual",
"size": 1485762,
"createdAt": "2024-12-28T16:35:00Z"
}
Get Recording URL
GET /recordings/{recording_id}/url
Response:
{
"url": "https://storage.edesy.in/recordings/call_def456.mp3?token=...",
"expiresAt": "2024-12-28T17:35:00Z"
}
Phone Numbers
List Phone Numbers
GET /phone-numbers
Response:
{
"data": [
{
"id": "pn_mno345",
"number": "+14155559876",
"provider": "twilio",
"agentId": "agent_abc123",
"capabilities": ["voice", "sms"],
"status": "active"
}
]
}
Assign Agent to Number
PATCH /phone-numbers/{phone_number_id}
Request Body:
{
"agentId": "agent_abc123"
}
Webhooks
List Webhook Deliveries
GET /webhooks/deliveries
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
event |
string | Filter by event type |
status |
string | success, failed, pending |
from |
datetime | Start date |
Response:
{
"data": [
{
"id": "del_pqr678",
"event": "call.ended",
"url": "https://example.com/webhook",
"status": "success",
"statusCode": 200,
"attempts": 1,
"createdAt": "2024-12-28T16:35:00Z"
}
]
}
Retry Webhook
POST /webhooks/deliveries/{delivery_id}/retry
Analytics
Get Usage Stats
GET /analytics/usage
Query Parameters:
| Parameter | Type | Description |
|---|---|---|
from |
datetime | Start date |
to |
datetime | End date |
agentId |
string | Filter by agent |
granularity |
string | hour, day, week, month |
Response:
{
"period": {
"from": "2024-12-01T00:00:00Z",
"to": "2024-12-28T23:59:59Z"
},
"totals": {
"calls": 5000,
"duration": 250000,
"cost": 125.50
},
"byProvider": {
"stt": {"deepgram": 4500, "google": 500},
"tts": {"cartesia": 4800, "elevenlabs": 200},
"llm": {"gemini": 4900, "openai": 100}
},
"timeSeries": [
{"date": "2024-12-01", "calls": 150, "duration": 7500},
{"date": "2024-12-02", "calls": 180, "duration": 9000}
]
}
Errors
All errors follow this format:
{
"error": {
"code": "invalid_request",
"message": "The 'to' field must be a valid phone number",
"details": {
"field": "to",
"value": "invalid-number"
}
}
}
Error Codes
| Code | HTTP Status | Description |
|---|---|---|
invalid_request |
400 | Invalid request parameters |
unauthorized |
401 | Invalid or missing API key |
forbidden |
403 | Insufficient permissions |
not_found |
404 | Resource not found |
rate_limited |
429 | Too many requests |
internal_error |
500 | Server error |
Rate Limits
| Endpoint | Limit |
|---|---|
| Create calls | 100/minute |
| List endpoints | 1000/minute |
| All other | 500/minute |
Rate limit headers:
X-RateLimit-Limit: 100
X-RateLimit-Remaining: 95
X-RateLimit-Reset: 1703779800
Next Steps
- WebSocket Protocol - Real-time communication
- Webhooks - Event notifications
- SDKs - Client libraries