Skip to main content

Voice API

Build powerful voice applications with programmable calls, text-to-speech, speech recognition, call recording, and interactive IVR systems.

🚀 Quick Start​

curl -X POST https://api.afriroute.ai/api/v1/voice/calls \
-H "Authorization: Bearer $AFRIROUTE_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"to": "+251911234567",
"from": "+251912000000",
"answer_url": "https://yourapp.com/voice/answer"
}'

📞 Making Calls​

Initiate Call​

POST /v1/voice/calls
const response = await fetch('https://api.afriroute.ai/api/v1/voice/calls', {
method: 'POST',
headers: {
'Authorization': 'Bearer $AFRIROUTE_API_KEY',
'Content-Type': 'application/json'
},
body: JSON.stringify({
to: '+251911234567',
from: '+251912000000',
answer_url: 'https://yourapp.com/voice/answer',
event_url: 'https://yourapp.com/voice/events'
})
});

const data = await response.json();
console.log(data.call_id); // call_abc123

🎙️ NCCO (Call Control)​

Control calls using Nexus Call Control Objects (JSON instructions).

Text-to-Speech​

[
{
"action": "talk",
"text": "Welcome to AfriRoute. Please hold while we connect you.",
"language": "en-US",
"style": 1,
"premium": false
}
]

Play Audio​

[
{
"action": "stream",
"streamUrl": ["https://yourapp.com/audio/welcome.mp3"],
"loop": 1
}
]

Connect to Phone​

[
{
"action": "connect",
"endpoint": [
{
"type": "phone",
"number": "+251911234567"
}
]
}
]

IVR Menu​

app.post('/voice/answer', (req, res) => {
const ncco = [
{
action: 'talk',
text: 'Welcome to customer support. Press 1 for sales, 2 for support, or 3 for billing.'
},
{
action: 'input',
eventUrl: ['https://yourapp.com/voice/dtmf'],
maxDigits: 1,
timeOut: 10
}
];

res.json(ncco);
});

app.post('/voice/dtmf', (req, res) => {
const digit = req.body.dtmf;

const departments = {
'1': { number: '+251911111111', name: 'Sales' },
'2': { number: '+251922222222', name: 'Support' },
'3': { number: '+251933333333', name: 'Billing' }
};

const dept = departments[digit];

if (dept) {
res.json([
{
action: 'talk',
text: `Connecting you to ${dept.name}`
},
{
action: 'connect',
endpoint: [{ type: 'phone', number: dept.number }]
}
]);
} else {
res.json([
{
action: 'talk',
text: 'Invalid selection. Goodbye.'
}
]);
}
});

🎤 Speech Recognition​

Convert speech to text in real-time.

[
{
"action": "talk",
"text": "Please say your account number after the beep."
},
{
"action": "input",
"type": ["speech"],
"speech": {
"uuid": ["call_abc123"],
"endOnSilence": 2.0,
"language": "en-US",
"context": ["account", "number", "digits"]
},
"eventUrl": ["https://yourapp.com/voice/speech"]
}
]
app.post('/voice/speech', (req, res) => {
const { speech } = req.body;

if (speech.results && speech.results.length > 0) {
const transcript = speech.results[0].text;
console.log(`User said: ${transcript}`);

res.json([
{
action: 'talk',
text: `You said: ${transcript}. Is that correct?`
}
]);
}
});

📼 Call Recording​

[
{
"action": "record",
"eventUrl": ["https://yourapp.com/voice/recording"],
"endOnSilence": 3,
"endOnKey": "#",
"beepStart": true
}
]

📥 Inbound Calls​

app.post('/voice/inbound', (req, res) => {
const { from, to, conversation_uuid } = req.body;

console.log(`Inbound call from ${from} to ${to}`);

res.json([
{
action: 'talk',
text: 'Thank you for calling. Your call is important to us.'
},
{
action: 'connect',
endpoint: [
{
type: 'phone',
number: '+251911234567' // Your support line
}
]
}
]);
});

🔔 Webhooks​

Call Events​

app.post('/voice/events', (req, res) => {
const { status, duration, from, to } = req.body;

console.log(`Call ${status}: ${from} → ${to} (${duration}s)`);

// Update database
await updateCallLog({
status,
duration,
from,
to,
timestamp: new Date()
});

res.sendStatus(200);
});

Event Types​

EventDescription
startedCall initiated
ringingPhone is ringing
answeredCall answered
completedCall ended normally
failedCall failed
rejectedCall rejected by recipient
busyRecipient busy
timeoutNo answer

📞 Advanced IVR​

Multi-Level Menu​

function buildMainMenu() {
return [
{
action: 'talk',
text: 'Main menu. Press 1 for account information, 2 for technical support, or 0 for operator.'
},
{
action: 'input',
eventUrl: ['https://yourapp.com/voice/main-menu'],
maxDigits: 1
}
];
}

function buildAccountMenu() {
return [
{
action: 'talk',
text: 'Account menu. Press 1 for balance, 2 for recent transactions, or 9 to go back.'
},
{
action: 'input',
eventUrl: ['https://yourapp.com/voice/account-menu'],
maxDigits: 1
}
];
}

Call Queuing​

[
{
"action": "talk",
"text": "All agents are currently busy. You are number 3 in the queue."
},
{
"action": "stream",
"streamUrl": ["https://yourapp.com/audio/hold-music.mp3"],
"loop": 0
}
]

🌍 Available Languages​

Text-to-Speech: 40+ languages and accents

  • English (US, UK, AU, IN, etc.)
  • French, Portuguese, Arabic, Swahili
  • Amharic (Ethiopia), Hausa (Nigeria), Yoruba
  • View all languages →

Speech Recognition: 20+ languages

  • English, French, Portuguese, Arabic
  • Swahili, Amharic, Yoruba, Zulu

💡 Best Practices​

IVR Design​

  • Keep menus simple - max 5 options per level
  • Repeat options - add "Press 9 to hear options again"
  • Provide escape hatch - "Press 0 for operator" on every menu
  • Use familiar patterns - 1-9 for options, 0 for operator, * to go back

Voice Quality​

  • Use premium TTS voices for professional sound
  • Optimize audio files - 8kHz mono WAV or 16kbps MP3
  • Test on real phones - sound quality varies by carrier
  • Implement fallbacks - if speech recognition fails, use DTMF

Performance​

  • Cache NCCO responses for static menus
  • Use webhooks for events - track all call states
  • Implement timeouts - 10s for input, 30s for speech
  • Log all interactions for debugging and analytics

User Experience​

  • Speak clearly and slowly in TTS
  • Provide progress updates - "Please hold while we look that up"
  • Confirm actions - "Press 1 to confirm, 2 to cancel"
  • Offer callback option - save waiting time

💰 Pricing​

TypePrice/MinuteNotes
Outbound (Local)$0.05Within same country
Outbound (International)$0.15Cross-border
Inbound$0.02Receive calls
TTS (Standard)$0.01Basic voices
TTS (Premium)$0.03Neural voices
Recording$0.005Per minute recorded

View detailed pricing →

📊 Call Analytics​

Track performance in dashboard:

  • ✅ Answer rate
  • ⏱️ Average call duration
  • 🔄 Call outcomes (completed, failed, busy)
  • 📈 Peak hours analysis
  • 💬 Menu selections

🛠️ SDKs​

// JavaScript
const afriroute = require('@afriroute/sdk');
const voice = new afriroute.Voice('$AFRIROUTE_API_KEY');

const call = await voice.createCall({
to: '+251911234567',
from: '+251912000000',
answerUrl: 'https://yourapp.com/voice/answer'
});
# Python
from afriroute import Voice

voice = Voice(api_key='$AFRIROUTE_API_KEY')
call = voice.create_call(
to='+251911234567',
from_='+251912000000',
answer_url='https://yourapp.com/voice/answer'
)

Need help? Contact Support → | View Code Examples →