Voice API
Server-side TTS for AI receptionists and products. Send text in Kinyarwanda, English, or French — get a WAV URL back.
v1 live
Create API key
1. Get an API key
- Create an account at ijwilab.com
- Open Dashboard → API keys
- Create a key and copy it once (shown only at creation)
2. Endpoints
| Method | Path | Auth | Purpose |
|---|---|---|---|
| POST | /api/v1/tts.php |
API key | Synthesize speech (WAV URL) |
| POST | /api/v1/tts-stream.php |
API key | Stream PCM for live calls (~500ms first audio) |
| GET | /api/v1/voices.php |
None | List languages & speakers |
| GET | /api/v1/health.php |
None | API readiness |
3. Synthesize speech
Request
curl -sS https://ijwilab.com/api/v1/tts.php \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": "Muraho, murakaza neza kuri IjwiLab.",
"language": "rw",
"speaker_id": 0
}'
Body fields
| Field | Type | Required | Notes |
|---|---|---|---|
input | string | yes | Text to speak (max 10,000 chars) |
language | string | no | rw (default), en, or fr |
speaker_id | int | no | 0–2 for rw/fr; 0–4 for en |
Success response
{
"output_url": "https://ijwilab.com/generated/audio_….wav",
"seconds": 3.42,
"language": "rw",
"speaker_id": 0,
"billing": {
"kinyarwanda_free": false,
"api_usage": true,
"tokens_charged": 1,
"token_balance": 49,
"free_uses_remaining": 4
}
}
3b. Realtime stream (live calls)
curl -sS -D - https://ijwilab.com/api/v1/tts-stream.php \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"input": "Hello, thanks for calling. How can I help?",
"language": "en",
"speaker_id": 0,
"format": "pcm16_8k"
}' \
--output reply.pcm
Body fields
| Field | Type | Required | Notes |
|---|---|---|---|
input | string | yes | Turn text (max 4,000 chars) |
language | string | no | rw, en, or fr |
speaker_id | int | no | Same as /tts.php |
format | string | no | pcm16_8k (default), pcm16_16k, pcm16_24k, or mulaw_8k (Twilio / PSTN) |
Response
- Body is raw audio (not JSON). Play or pipe chunks as they arrive.
X-Ijw-Ttfa-Ms— server time-to-first-audio in millisecondsContent-Type—audio/l16oraudio/basic(μ-law)
4. Voices
Kinyarwanda (rw) · tokens
| speaker_id | Name | Group |
|---|---|---|
0 |
Ingabire | kinyarwanda |
1 |
Irakoze | kinyarwanda |
2 |
Mugenzi | kinyarwanda |
English (en) · tokens
| speaker_id | Name | Group |
|---|---|---|
0 |
Sarah | us-english |
1 |
Ryan | us-english |
2 |
Emma | us-english |
3 |
Amara | african-english |
4 |
Kwame | african-english |
French (fr) · tokens
| speaker_id | Name | Group |
|---|---|---|
0 |
Julie | french |
1 |
Thomas | french |
2 |
Camille | french |
5. AI receptionist pattern
- Your LLM / NLU decides the reply text and language (
rw/en/fr) POST /api/v1/tts-stream.phpwith that text + language + speaker +format(mulaw_8korpcm16_8k)- Play the audio stream on the call as soon as the first bytes arrive (do not wait for the full utterance)
English greeting
curl -sS https://ijwilab.com/api/v1/tts.php \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"Hello, thank you for calling. How can I help you today?","language":"en","speaker_id":3}'
French greeting
curl -sS https://ijwilab.com/api/v1/tts.php \
-H "Authorization: Bearer YOUR_API_KEY" \
-H "Content-Type: application/json" \
-d '{"input":"Bonjour, bienvenue. Comment puis-je vous aider?","language":"fr","speaker_id":0}'
6. Errors
| HTTP | Meaning |
|---|---|
401 | Missing or invalid API key |
402 | Not enough tokens (rw/en/fr on API) — API top-up (min 289 tokens) |
410 | Voice cloning retired |
429 | Rate limit (max 30 TTS requests/minute per key) |
405 | Wrong HTTP method |
503 | Health check reports backend not ready |
7. Pricing snapshot
- Studio Kinyarwanda (rw): free
- API (rw / en / fr): tokens · $0.04/token
- API top-up minimum: 289 tokens
- 5 free short trial generations per account (under 2 min), then tokens