Speech to text

Upload an audio file and get a transcript back — Persian by default, m4a and webm handled without conversion.

POST /v1/audio/transcriptions takes one audio file and returns its text — the same shape OpenAI's Whisper endpoint uses, multipart form and all, so an existing client library already knows how to call it.

POST/v1/audio/transcriptions
ParameterTypeDescription
file
Required
fileThe audio. Any container ffmpeg reads: m4a, mp3, wav, webm/opus, and more.
model
Optional
stringThe deployment name. The engine underneath is Whisper large-v3 — see below for why that's the default rather than the Persian fine-tune that wins on short clips.
Default: larsa-stt
language
Optional
stringA Whisper language name (persian, english, spanish, …). The default is Persian — set this explicitly for anything else, or the audio gets decoded as if it were Persian.
Default: persian
response_format
Optional
"json" | "text"json returns {text, duration, processing_time}. text returns the transcript as a plain body. Neither carries word or segment timestamps — there is no verbose_json here.
Default: json
fusion
Optional
booleanReconcile three Whisper variants instead of running one — see below. Roughly doubles the time, and is worth it for anything unattended.
Default: false
Transcribing a file
curl -s https://api.console.larsa.larsima.com/v1/audio/transcriptions \
  -H "Authorization: Bearer $LARSA_API_KEY" \
  -F file=@voice.m4a \
  -F model=larsa-stt \
  -F language=persian \
  -F response_format=json

# {"text":"مهلت تجدیدنظرخواهی از رأی دادگاه بیست روز است.",
#  "duration":4.58,"processing_time":1.12}

The phone recording that usually breaks this

A voice note from a phone is m4a, and m4a keeps its index in a trailing atom at the *end* of the file — a decoder has to seek backwards to find it. Fed through a pipe, ffmpeg cannot seek, exits 0 having produced nothing, and the request "succeeds" with an empty transcript and no error anywhere. This service always writes the upload to a temp file first and decodes from that, specifically so this doesn't happen. Send the file exactly as your phone recorded it — m4a, webm/opus, whatever your caller produces — there is no need to convert it yourself.

Long audio: cut on silence, not on a clock

There's no length limit beyond the edge's 200MB upload cap. Long audio is cut at the quietest gaps — never longer than 25 seconds a segment, never mid-word — rather than at fixed 30-second boundaries. That distinction is not cosmetic: a fixed-window chunker on the same audio, same model, silently dropped a whole passage from the middle of a recording — 69.6% word error rate against 38.5% for the version that cuts on silence.

fusion: four ears instead of one

Set fusion=true and three Whisper variants transcribe the same audio independently; a fourth model reads all three candidates and reconstructs what none of them got right alone. Measured on short clips, this took the error rate from 34.4% to 15.6%. It roughly doubles the time, and it's off by default for that reason — but for anything unattended, it earns the cost. On one real voice note the raw transcript garbled "کلاهبرداری" (fraud) into "نکلاه برداری", and reading that garbled word changed a downstream model's answer from *the law protects you* to *you may be prosecuted*. Fusion is the guard against exactly that.

cURL
curl -s https://api.console.larsa.larsima.com/v1/audio/transcriptions \
  -H "Authorization: Bearer $LARSA_API_KEY" \
  -F file=@voice.m4a \
  -F model=larsa-stt \
  -F language=persian \
  -F fusion=true

# {"text":"...", "duration":4.58, "processing_time":2.3,
#  "candidates":["...", "...", "..."]}
With fusion=true, the response adds candidates: the three raw transcripts that went into reconciling text. Worth logging if you ever need to see what the recognisers actually disagreed about.

Why Whisper large-v3 and not the Persian specialist

A Persian fine-tune of Whisper wins the short-clip leaderboard. It also has a failure mode large-v3 doesn't: on a 63-second passage it fell into a repetition loop — "دادخواهم، دادخواهم، …" — and scored 90.7% word error rate where large-v3 scored 38.5% on the same audio. Voice notes are long. The short-clip winner was the wrong default.

Model testedRead speech (Common Voice)Spontaneous speech (voice-note-like)
Whisper large-v3 — larsa-stt, default53.0% WER34.0% WER
Whisper large-v3-turbo67.1% WER36.9% WER
Whisper large-fa (Persian fine-tune)52.4% WER55.8% WER

Measured on hezarai/common-voice-13-fa (read) and pourmand1376/asr-farsi-youtube-chunked-30-seconds (spontaneous), the same files through every model. Note that "read" and "spontaneous" rank the models differently — a single number from either test alone would be true and misleading.

Navigate Open esc Close