Abena AI API

Add African-language Text-to-Speech (speech from text) and Speech Recognition (text from speech) to any app. It works over plain HTTP, so you can use it from a website, a phone app, a server, or even just a terminal — no special library required.

The base URL for every endpoint is:

https://abena.mobobi.com/playground/api/v1

New here? Start free.

You get 50 free requests with no account and no API key. Just send a request and it works. See Free Tier below.

Free Tier (No Sign-Up)

You can try every endpoint without creating an account. Just leave out the API key and your first 50 requests are free.

  • 50 free requests to get started — no sign-up, no credit card.
  • Perfect for testing, demos, and learning how the API works.
  • Ready to build? Create a free account for your own API key — you'll get extra free headroom on top of the no-account allowance, plus a dashboard to track usage and manage your keys.

First request to a voice may take ~10–15 seconds

The very first time a particular voice is used, the model is loaded and prepared (this happens fully on our server, offline). After that, the same voice responds in about a second. If your first call feels slow, that's normal — just let it finish.

Your First Request

Copy this into a terminal. It turns text into speech using the Ghanaian-accent English voice akua_eng and saves the result to speech.wav. No API key needed.

curl -s -X POST https://abena.mobobi.com/playground/api/v1/tts/synthesize/ \
  -H "Content-Type: application/json" \
  -d '{"text": "Hello! Welcome to Abena AI.", "voice": "akua_eng"}' \
  | python3 -c "import sys,json,base64; open('speech.wav','wb').write(base64.b64decode(json.load(sys.stdin)['audio_base64'])); print('Saved speech.wav')"

Now open speech.wav and listen. That's it — you've used the API.

Text-to-Speech

Send some text and a voice; get back audio. The audio is returned as Base64-encoded WAV inside a JSON response (this makes it easy to use from any language and from the browser).

Endpoint

POST https://abena.mobobi.com/playground/api/v1/tts/synthesize/

Request body (JSON)

FieldRequiredDescription
textYesThe text to speak. Up to 500 characters.
voiceYesA voice ID, e.g. akua_eng, chioma_eng, chioma_whispering_eng, abena_twi_high. See TTS Voices.
speedNoSpeaking speed. 1.0 is normal, 0.5 is slowest, 2.0 is fastest. Default 1.0.

Response (JSON)

{
  "status": "success",
  "audio_base64": "UklGRiQ...",   // the WAV file, Base64-encoded
  "duration_seconds": 2.91,
  "mime_type": "audio/wav"
}

Example: curl

curl -X POST https://abena.mobobi.com/playground/api/v1/tts/synthesize/ \
  -H "Content-Type: application/json" \
  -d '{"text": "Akwaaba, wo ho te sen?", "voice": "abena_twi_high", "speed": 1.0}'

Twi tip

Use abena_twi_high for the newer, more natural single-speaker Twi voice. Use abena_twi_lite when you want the lighter voice, which can sound clearer on some short phrases. For longer Twi text, write naturally and use commas to break long ideas into short phrases.

Speech Recognition

Send an audio file; get back the text. Upload the file as a normal form field named audio_file (this is multipart/form-data, the same thing a web form uses to upload a file).

Endpoint

POST https://abena.mobobi.com/playground/api/v1/asr/transcribe/

Form fields

FieldRequiredDescription
audio_fileYesYour audio file. Up to 2 minutes (120 seconds), 8 MB max.
languageNoen (English) or gpe (Ghanaian Pidgin). Default en. See ASR Languages.
reference_textNoIf you know the correct text, include it to also get accuracy/WER scores.

Supported audio formats: WAV/PCM, MP3, M4A/AAC, FLAC, OGG, and other common formats that FFmpeg can decode. For the most predictable batch evaluations, use mono WAV at 16 kHz. Non-WAV uploads are converted on the server before transcription.

Response (JSON)

{
  "text": "hello how are you",
  "transcription": "hello how are you",
  "language": "en",
  "confidence": 85.0,
  "duration_seconds": 3.2
}

Example: curl

curl -X POST https://abena.mobobi.com/playground/api/v1/asr/transcribe/ \
  -F "audio_file=@recording.wav" \
  -F "language=en"

TTS Voices

Use the preferred voice ID below in your request. You can always fetch the live list from GET /playground/api/v1/tts/voices.json. Older short IDs and playground model IDs like akua, en-ng-chioma, en-ng-chioma-whispering, swahili, and nigerian_pidgin_s are still accepted as aliases. The old Twi ID abena_twi has been replaced by explicit High and Lite options.

Voice IDNameLanguageCountryGender
abena_twi_highGhanaAbena HighTwi (Akan, newer natural voice)GhanaFemale
abena_twi_liteGhanaAbena LiteTwi (Akan, lighter voice)GhanaFemale
kobby_gpeGhanaKobbyGhanaian Pidgin EnglishGhanaMale
akua_engGhanaAkuaEnglish (Ghanaian accent)GhanaFemale
kwabena_engGhanaKwabenaEnglish (Ghanaian accent)GhanaMale
chioma_engChiomaEnglish (Nigerian accent, energetic)NigeriaFemale
chioma_whispering_engChiomaEnglish (Nigerian accent, whispering)NigeriaFemale
mawuli_eweMawuliEweGhanaMale
james_pcmJamesNigerian Pidgin EnglishNigeriaMale
amani_swhAmaniSwahiliKenyaFemale
abubakar_hauAbubakarHausaNigeriaMale
folami_yorFolamiYorubaNigeriaFemale

ASR Languages

Use the language code below for transcription. You can also fetch the live list from GET /playground/api/v1/asr/voices.json.

CodeLanguageCountry
enGhanaEnglish (Ghanaian accent)Ghana
gpeGhanaGhanaian Pidgin EnglishGhana

More languages, including Akan Twi speech recognition, are coming soon.

Errors & Limits

Every error returns JSON with a helpful message (TTS) or error (ASR) field. Common status codes:

StatusMeaningWhat to do
200SuccessUse the result.
400Bad requestCheck your fields (e.g. missing text, unknown voice, speed out of range).
401Free limit reachedYou've used your 50 free requests. Get an API key to continue.
413Too largeShorten the text (TTS, 500 chars) or use a smaller audio file (ASR, 8 MB max).
429Too many requestsSlow down and retry in a moment.
500 / 503Server issueRetry shortly. If it persists, contact support.

Try It Live

This runs right here in your browser, using the free tier (no key). Type something, pick a voice, and press the button. Remember: the first time you use a voice it may take ~10–15 seconds to warm up.

Use From Any Language

The API is just HTTP + JSON, so it works everywhere. Here are the most common ways to call Text-to-Speech and Speech Recognition.

JavaScript (browser or Node.js)

const res = await fetch(
  "https://abena.mobobi.com/playground/api/v1/tts/synthesize/",
  {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ text: "Hello!", voice: "akua_eng" })
  }
);
const data = await res.json();
// data.audio_base64 is a Base64 WAV you can play or save
new Audio("data:audio/wav;base64," + data.audio_base64).play();

Python

Uses Python's built-in HTTP client, so there is no extra package to install.

import base64, json
from urllib.request import Request, urlopen

payload = json.dumps({"text": "Hello!", "voice": "akua_eng"}).encode("utf-8")
req = Request(
    "https://abena.mobobi.com/playground/api/v1/tts/synthesize/",
    data=payload,
    headers={"Content-Type": "application/json", "Accept": "application/json"},
    method="POST",
)
with urlopen(req, timeout=120) as res:
    data = json.loads(res.read().decode("utf-8"))

with open("speech.wav", "wb") as f:
    f.write(base64.b64decode(data["audio_base64"]))
print("Saved speech.wav")

Speech Recognition (Python)

import json, mimetypes, uuid
from pathlib import Path
from urllib.request import Request, urlopen

audio_path = Path("recording.wav")
boundary = "----abena-" + uuid.uuid4().hex
audio_bytes = audio_path.read_bytes()
content_type = mimetypes.guess_type(audio_path.name)[0] or "application/octet-stream"

body = (
    f"--{boundary}\r\n"
    'Content-Disposition: form-data; name="language"\r\n\r\n'
    "en\r\n"
    f"--{boundary}\r\n"
    f'Content-Disposition: form-data; name="audio_file"; filename="{audio_path.name}"\r\n'
    f"Content-Type: {content_type}\r\n\r\n"
).encode("utf-8") + audio_bytes + f"\r\n--{boundary}--\r\n".encode("utf-8")

req = Request(
    "https://abena.mobobi.com/playground/api/v1/asr/transcribe/",
    data=body,
    headers={
        "Content-Type": f"multipart/form-data; boundary={boundary}",
        "Accept": "application/json",
    },
    method="POST",
)
with urlopen(req, timeout=120) as res:
    data = json.loads(res.read().decode("utf-8"))
print(data["text"])

Example App

Here is a complete, working web page. Save it as index.html and open it in any browser — no installation, no build step, no API key. It's the same idea as the live demo above.

<!DOCTYPE html>
<html>
<head>
  <meta charset="utf-8">
  <title>Abena AI — Text to Speech</title>
</head>
<body style="font-family: sans-serif; max-width: 600px; margin: 40px auto;">
  <h1>Text to Speech</h1>

  <textarea id="text" rows="3" style="width:100%">Akwaaba! Welcome to Abena AI.</textarea>

  <select id="voice">
    <option value="akua_eng">Akua (English, Ghana)</option>
    <option value="chioma_eng">Chioma energetic (English, Nigeria)</option>
    <option value="chioma_whispering_eng">Chioma whispering (English, Nigeria)</option>
    <option value="abena_twi_high">Abena High (Twi)</option>
    <option value="abena_twi_lite">Abena Lite (Twi)</option>
    <option value="kobby_gpe">Kobby (Ghanaian Pidgin)</option>
  </select>

  <button onclick="speak()">Speak</button>
  <p id="status"></p>
  <audio id="player" controls></audio>

  <script>
    const API = "https://abena.mobobi.com/playground/api/v1/tts/synthesize/";

    async function speak() {
      const status = document.getElementById("status");
      status.textContent = "Generating… (first use of a voice can take ~15s)";

      const res = await fetch(API, {
        method: "POST",
        headers: { "Content-Type": "application/json" },
        body: JSON.stringify({
          text: document.getElementById("text").value,
          voice: document.getElementById("voice").value
        })
      });

      const data = await res.json();
      if (data.status === "success") {
        document.getElementById("player").src =
          "data:audio/wav;base64," + data.audio_base64;
        document.getElementById("player").play();
        status.textContent = "Done (" + data.duration_seconds + "s)";
      } else {
        status.textContent = "Error: " + (data.message || "try again");
      }
    }
  </script>
</body>
</html>

Want the full source plus more examples (Python, Node.js)? See abena-ai-api on GitHub.

API Keys (Optional)

You do not need an API key for the free tier examples above. Just send a request and it works.

When you are ready to build beyond the no-account allowance, create a free account from your dashboard and include your key in one of these ways:

# Option 1 (recommended): Authorization header
Authorization: Bearer YOUR_API_KEY

# Option 2: X-API-Key header
X-API-Key: YOUR_API_KEY

# Option 3: query string (handy for quick tests)
?api_key=YOUR_API_KEY