Mawj Mawj Speech to Text / API Reference Playground

API Reference

The Mawj Speech to Text API converts Arabic speech to text. Upload an audio file and get back the transcript, with timestamps for each segment and word.

Base URL:

https://mawj-stt.prod.mawj.space

Requests use multipart/form-data. Responses are JSON.

Authentication

Send your API key in the Authorization header of every request:

Authorization: Bearer <api-key>

Rate limits

Each API key has these limits:

  • Requests per minute
  • Concurrent requests: requests being processed at the same time
  • Audio minutes: the total minutes of audio the key can transcribe, if your key has this limit. Failed requests are not counted, and a file longer than the minutes left is rejected.

Successful responses include these headers:

HeaderDescription
X-RateLimit-LimitRequests allowed per minute.
X-RateLimit-RemainingRequests remaining before the limit is reached.

If you exceed a limit, the API returns 429 Too Many Requests. For the per-minute limit, the Retry-After header gives the number of seconds to wait. A file longer than your key's total audio minutes returns 413 Content Too Large.

Errors

Errors return a JSON body with a detail message:

{ "detail": "Invalid or missing API key" }
StatusMeaning
400 Bad RequestThe file could not be read as audio.
401 UnauthorizedThe API key is missing or invalid.
413 Content Too LargeThe file is longer than your key's total audio minutes.
422 Unprocessable EntityA field is missing or invalid, for example hotword_weight outside 1–100.
429 Too Many RequestsA limit was reached.
500 Internal Server ErrorTranscription failed. You can retry the request.
503 Service UnavailableThe service is starting. Retry shortly.

Transcribe audio

POST /api/v1/audio/transcribe

Transcribes an audio file.

Request

FieldTypeDescription
filerequiredfileThe audio file: WAV, FLAC, MP3, OGG, WebM, or M4A.
hotwordsoptionalstringWords to boost, as a comma-separated list (الرياض,جدة) or a JSON array (["الرياض", "جدة"]). See Hotwords.
hotword_weightoptionalnumberHow strongly hotwords are boosted, from 1 to 100. Default 10.
word_timestampsoptionalbooleanInclude timestamps for each word. Default true.

Examples

cURL
curl -X POST "https://mawj-stt.prod.mawj.space/api/v1/audio/transcribe" \
  -H "Authorization: Bearer $MAWJ_API_KEY" \
  -F "file=@audio.wav" \
  -F "hotwords=موج"
Python
import requests

with open("audio.wav", "rb") as audio:
    response = requests.post(
        "https://mawj-stt.prod.mawj.space/api/v1/audio/transcribe",
        headers={"Authorization": f"Bearer {API_KEY}"},
        files={"file": audio},
        data={"hotwords": "موج"},
    )
response.raise_for_status()

print(response.json()["text"])
JavaScript (Node.js 20+)
import { openAsBlob } from "node:fs";

const form = new FormData();
form.append("file", await openAsBlob("audio.wav"), "audio.wav");
form.append("hotwords", "موج");

const response = await fetch("https://mawj-stt.prod.mawj.space/api/v1/audio/transcribe", {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.MAWJ_API_KEY}` },
  body: form,
});
const result = await response.json();
console.log(result.text);

Hotwords

Hotwords help the model recognize specific words, such as names and places.

  • Write hotwords in Arabic. Other entries are ignored.
  • If a hotword is still missed, increase hotword_weight. If it appears where it wasn't said, decrease it.

Response

Response
{
  "text": "مرحبا بكم في موج",
  "filename": "audio.wav",
  "processing_time_ms": 52.4,
  "segments": [
    {
      "start": 0.28,
      "end": 1.96,
      "text": "مرحبا بكم في موج",
      "confidence": 0.95,
      "words": [
        { "word": "مرحبا", "start": 0.28, "end": 0.71, "conf": 0.97 },
        { "word": "بكم", "start": 0.74, "end": 1.02, "conf": 0.95 },
        { "word": "في", "start": 1.06, "end": 1.18, "conf": 0.93 },
        { "word": "موج", "start": 1.22, "end": 1.46, "conf": 0.94 }
      ]
    }
  ],
  "metadata": {
    "model_name": "mawj_telephony_model",
    "language": "ar",
    "segments_count": 1,
    "total_duration": 2.1,
    "word_timestamps": true,
    "speed_ratio": 40.1,
    "device": "cuda",
    "num_words": 4,
    "queue_wait_ms": 0.0
  }
}
FieldTypeDescription
textstringThe full transcript.
filenamestringName of the uploaded file.
processing_time_msnumberTime the server spent transcribing, in milliseconds.
segmentsarrayThe transcript split into segments. See below.
metadataobjectDetails about the request. See below.

Segments

FieldTypeDescription
startnumberStart time, in seconds.
endnumberEnd time, in seconds. Can be up to 0.5 seconds after the last word.
textstringText of the segment.
confidencenumberConfidence, from 0 to 1.
wordsarray | nullEach word with its text (word), start and end times, and confidence (conf). null when word_timestamps is false.

Metadata

FieldTypeDescription
model_namestringThe model used: mawj_telephony_model.
languagestringAlways ar.
total_durationnumberAudio length, in seconds.
speed_rationumberSeconds of audio processed per second.
segments_countintegerNumber of segments.
num_wordsintegerNumber of words.
word_timestampsbooleanWhether word timestamps were requested.
devicestringcuda (GPU) or cpu.
queue_wait_msnumberTime spent waiting before processing started, in milliseconds.

Health check

GET /health

Returns the service status. No API key is needed.

Response
{
  "status": "healthy",
  "model": "mawj_telephony_model",
  "auth_required": true
}