Ongea na Ngamia is the synchronous voice flow for applications that let people speak naturally in Kiswahili. A typical request sends a voice note to speech-to-text, passes the transcript to a selected text model with a Tanzanian Kiswahili response instruction, and optionally synthesizes the answer back into audio.
The portal documents three public routes. Use the direct routes when you want control over each stage; use the combined route when your product needs one request and one JSON result.
| Capability | Endpoint | Response |
|---|---|---|
| Speech-to-text | POST /v1/audio/transcriptions | JSON transcription and optional usage |
| Text-to-speech | POST /v1/audio/speech | Raw MP3 or PCM bytes |
| Combined Ongea flow | POST /v1/voice/responses | JSON transcript, text response, and optional base64 audio |
Voice is billed in Ngamia credits at each successful stage. Transcription is settled from the upstream-reported usage.cost; speech is estimated from the model's pricing. Check the live model catalog and balance before production rollout, and do not assume that every text model supports transcription or speech output.
Every model and voice field below is optional: the gateway applies server defaults configured by your deployment (VOICE_DEFAULT_STT_MODEL, VOICE_DEFAULT_TEXT_MODEL, VOICE_DEFAULT_TTS_MODEL, VOICE_DEFAULT_VOICE). Omit a field to use the configured model instead of hardcoding a catalog slug that the upstream may retire. The live catalog refreshes when cmd/seed-catalog runs — see the API repo for details.
1. Speech-to-text
/v1/audio/transcriptionsAPI key or JWTNgamia accepts either JSON with raw base64 audio or OpenAI-compatible multipart/form-data. The model (default openai/whisper-1) must be a public value returned by GET /v1/models whose output_modalities contains transcription.
JSON with base64 audio
input_audio.data is the raw base64 string. It is not a data: URI. The audio format must match the bytes you send.
import base64
import os
import requests
with open("voice-note.mp3", "rb") as audio_file:
audio_base64 = base64.b64encode(audio_file.read()).decode("ascii")
response = requests.post(
"https://api.ngamia.cc/v1/audio/transcriptions",
headers={
"Authorization": "Bearer " + os.environ["NGAMIA_API_KEY"],
"Content-Type": "application/json",
},
json={
"model": "openai/whisper-1",
"language": "sw",
"input_audio": {
"data": audio_base64,
"format": "mp3",
},
},
timeout=90,
)
response.raise_for_status()
print(response.json()["text"])Multipart upload
curl https://api.ngamia.cc/v1/audio/transcriptions \
-H "Authorization: Bearer $NGAMIA_API_KEY" \
-F "model=openai/whisper-1" \
-F "language=sw" \
-F "file=@voice-note.mp3"| Field | JSON | Multipart | Description |
|---|---|---|---|
model | No | No | Transcription-capable model from the live catalog; omitted → configured STT default. |
input_audio.data | Yes | No | Raw base64 audio bytes. |
input_audio.format | Yes | No | wav, mp3, flac, m4a, ogg, webm, or aac; use the real format. |
file | No | Yes | The uploaded audio file. |
language | No | No | ISO-639-1 language hint. Use sw for Kiswahili voice notes. |
response_format | No | No | json by default; verbose_json may include additional provider-supported timing data. |
The gateway caps audio input at 25 MiB. Compressed formats such as MP3 are usually a better fit for mobile voice notes. Split unusually long recordings into smaller requests and apply your own duration policy before forwarding user content.
A successful response is JSON:
{
"text": "Habari, naomba unisaidie kuhusu malipo.",
"language": "sw",
"duration": 8.4,
"usage": {
"seconds": 8.4,
"input_tokens": 42,
"output_tokens": 12,
"total_tokens": 54
}
}X-Generation-Id, when returned, is a provider generation identifier for support correlation. Keep it with your application request id, but do not expose credentials or raw audio in support logs.
2. Text-to-speech
/v1/audio/speechAPI key or JWTSend text to a model whose output_modalities contains speech. The response is a raw audio stream, not JSON. The gateway supports mp3 and pcm; voice names are model-dependent, so use the selected model’s documented voice. response_format defaults to mp3, which matches plain playback.
import os
import requests
response = requests.post(
"https://api.ngamia.cc/v1/audio/speech",
headers={
"Authorization": "Bearer " + os.environ["NGAMIA_API_KEY"],
"Content-Type": "application/json",
},
json={
"model": "x-ai/grok-voice-tts-1.0",
"input": "Karibu Ngamia. Tunaweza kuzungumza kwa Kiswahili.",
"voice": "eve",
"response_format": "mp3",
"speed": 1.0,
},
timeout=90,
)
response.raise_for_status()
with open("reply.mp3", "wb") as audio_file:
audio_file.write(response.content)
print(response.headers.get("X-Generation-Id"))| Field | Required | Description |
|---|---|---|
model | No | Speech-capable model from GET /v1/models; omitted → configured TTS default. |
input | Yes | Text to synthesize; maximum 100,000 Unicode characters. |
voice | No | Voice identifier documented by the selected model; omitted → configured voice default. |
response_format | No | mp3 (default) or pcm; MP3 is convenient for playback and PCM suits low-latency pipelines. |
speed | No | A model-dependent playback multiplier; use the documented supported range. |
The response includes an audio Content-Type and may include X-Generation-Id. Save PCM with a format appropriate to your playback pipeline; do not rename raw PCM bytes as MP3.
3. Combined Ongea na Ngamia response
/v1/voice/responsesAPI key or JWTThe combined route accepts a JSON body with base64 audio. It runs transcription, text response generation, and optional speech synthesis in sequence. The default input and response language is Kiswahili (sw). Set response_language to en only when your user experience intentionally requests an English response.
{
"stt_model": "openai/whisper-1",
"text_model": "openai/gpt-4o-mini",
"tts_model": "x-ai/grok-voice-tts-1.0",
"audio_data": "<raw-base64-audio>",
"audio_format": "mp3",
"language": "sw",
"response_language": "sw",
"voice": "eve",
"response_format": "mp3",
"include_audio": true
}audio_data and audio_format are required. stt_model, text_model, tts_model, and voice are optional — omitted fields use the configured server defaults. Set include_audio to false when you only need the transcript and generated text; this avoids the speech stage and does not require a TTS model.
The response is JSON:
{
"transcript": "Habari, naomba unisaidie kuhusu malipo.",
"transcript_language": "sw",
"text": "Hakika. Tafadhali niambie unahitaji msaada gani kuhusu malipo.",
"audio_base64": "<generated-base64-audio>",
"audio_content_type": "audio/mpeg",
"speech_generation_id": "gen_..."
}Example request:
curl https://api.ngamia.cc/v1/voice/responses \
-H "Authorization: Bearer $NGAMIA_API_KEY" \
-H "Content-Type: application/json" \
-d '{
"stt_model": "openai/whisper-1",
"text_model": "openai/gpt-4o-mini",
"audio_data": "<raw-base64-audio>",
"audio_format": "mp3",
"language": "sw",
"response_language": "sw",
"include_audio": false
}'The text stage is instructed to preserve Tanzanian names, numbers, dates, TZS amounts, and payment references. Treat transcription and model output as untrusted content: your application must still validate amounts, authorization, and any action that could create a key, move money, or change an account.
Discover compatible models
Do not hardcode the illustrative model values above. Fetch the live catalog and select records by capability:
curl https://api.ngamia.cc/v1/models \
-H "Authorization: Bearer $NGAMIA_API_KEY"| Need | Catalog check |
|---|---|
| Transcribe audio | output_modalities contains transcription |
| Generate speech | output_modalities contains speech |
| Generate a text response | output_modalities contains text |
| Understand multimodal input | Check both input_modalities and supported_parameters |
| Estimate cost | Read the applicable token, image, or request price fields |
The catalog is paid-only by default and can change as models or prices change. Refresh it when your service starts and when a request returns a model-not-found or unsupported-modality error.
Credits, retries, and operational behavior
Each direct voice stage reserves and settles credits through the normal Ngamia ledger. Transcription is settled from the upstream-reported usage.cost in USD converted to credits at the configured rate; speech is settled from the model's pricing, or a nominal credit when the provider reports no usage. The reservation is capped so an unmetered check never blocks a normal account, and the actual charge never exceeds the account balance.
Use a unique Idempotency-Key only where the endpoint and your deployment explicitly support safe replay. Do not blindly replay raw audio or speech requests, because replaying a side-effecting or billable operation can create an unexpected charge. On network failure, first determine whether your application received a successful response, then decide whether to retry according to your own request policy.
Voice responses are synchronous and base64-encoded on the combined route. For production mobile applications, enforce client-side duration and size limits, show progress and cancellation states, and avoid retaining recordings by default.
Errors
| Status | Meaning | Action |
|---|---|---|
400 | Invalid JSON, audio, format, language, or model capability | Correct the request and use a compatible catalog model. |
401 | Missing or invalid credential | Refresh the JWT or use a valid server-side API key. |
402 | Insufficient credits | Ask the user to top up through the authenticated payment flow, then retry deliberately. |
404 | Unknown, disabled, or incompatible model | Refresh GET /v1/models; do not guess a provider model. |
413 | Payload or speech input exceeds a gateway limit | Compress or split audio, or shorten the text. |
429 | Rate limit exceeded | Retry with exponential backoff and jitter. |
502/503 | Upstream or provider availability failure | Retry only when safe, preserve request_id, and show a temporary failure. |
Non-success responses are JSON error objects even when the successful speech response is raw audio. Always check the HTTP status before writing a speech response to a file.
Security and privacy
Keep the API key on your server, not in a browser or mobile bundle. Voice notes can contain personal data, payment details, or confidential business information. Obtain any consent required for your use case, avoid sending recordings to logs or analytics, encrypt any retained media, apply an expiry, and delete it when no longer needed. See Security & data handling.
References
The transcription and speech flows align with the OpenAI audio API reference while staying compatible with Ngamia's credit and reservation model.