Guide · Speech APIs
Hindi speech-to-text API: transcribe calls with Mira.
Send us a recording of a Hindi or Hinglish call and get back who said what, and when. Hindi comes back in Devanagari and English in Latin script, as people mixed them, for ₹18 an hour of audio.
Use offline transcription for recorded phone calls.
| You have | Use | Billing |
|---|---|---|
| A recording of a past call | POST /v2/transcriptions (offline) |
₹18 per hour of audio |
| A call by one of your agents | GET /v2/calls/{id}/transcript, or the transcript in the call.processed webhook |
Part of the call |
| Live audio in your own app or bot | The Realtime API, with conversation.item.input_audio_transcription events |
Per minute, as a call |
| Live audio, recognition only | Standalone streaming recognition, in private preview | Ask us |
Offline transcription is built for phone calls in Hindi and Hinglish, and hears English, Gujarati, Tamil and Telugu too. language defaults to auto. Set hi or en if detection gets it wrong; the reference lists the other codes.
How accurate is Fourier STT on Hindi?
Fourier STT, our own Hindi speech recognition, scored 9.12% normalised word error rate on all 10,000 utterances of the RinggAI Hindi ASR benchmark. The speech-to-text model page has the table.
Two caveats. It’s read speech, not phone calls, and we’re not the best on every subset. So test with your own audio: transcribe a sample of your calls and have a Hindi speaker check it.
Upload a recording and check the job until it finishes.
Make a key under Developers in the sandbox, then upload:
curl -X POST https://sandbox.voice.miraiminds.co/v2/transcriptions \
-H "Authorization: Bearer $MIRAI_API_KEY" \
-H "Idempotency-Key: call-2026-10-02-0412" \
-F [email protected] \
-F context="A call to a university admissions desk about a course and its fees" \
-F vocabulary="Mira University, BBA, Aadhaar"
You get 202 Accepted with status: "queued". In Python:
import os
import time
import httpx
API = "https://sandbox.voice.miraiminds.co"
auth = {"Authorization": f"Bearer {os.environ['MIRAI_API_KEY']}"}
def submit(path: str, idempotency_key: str) -> dict:
with open(path, "rb") as f:
r = httpx.post(
f"{API}/v2/transcriptions",
headers={**auth, "Idempotency-Key": idempotency_key},
files={"file": (os.path.basename(path), f, "audio/wav")},
data={
"context": "A delivery company confirming an order and a refund",
"vocabulary": "refund, order",
},
timeout=600, # the answer comes after the whole file is uploaded
)
job = r.json()
if r.status_code != 202:
raise RuntimeError(f"{job['error']['code']}: {job['error']['message']}")
return job
def wait(job_id: str, timeout_secs: int = 3600) -> dict:
deadline = time.monotonic() + timeout_secs
delay = 1.0
while time.monotonic() < deadline:
r = httpx.get(f"{API}/v2/transcriptions/{job_id}", headers=auth, timeout=30)
if r.status_code in (429, 503):
time.sleep(float(r.headers.get("Retry-After", "5")))
continue
job = r.raise_for_status().json()
if job["status"] in ("completed", "failed"):
return job
time.sleep(delay)
delay = min(delay * 1.5, 5) # quick at first, then every 5 seconds
raise TimeoutError(job_id)
job = wait(submit("call.wav", idempotency_key="call-2026-10-02-0412")["id"])
if job["status"] == "failed":
print(job["error"]["code"], job["error"]["message"])
else:
for seg in job["segments"]:
print(f"{seg['start']:6.2f} {seg.get('speaker_id', '-')} {seg['speaker']}: {seg['text']}")
print(job["cost"])
A job goes queued, decoding, merging, then completed or failed. The docs put a typical job at about 10 seconds plus 15% of the recording’s length.
While it’s merging, the job carries a draft: the best single pass, with timestamps but no speakers, and English often in Devanagari. Show it as provisional.
Over 45 MB, send JSON with an https url instead (up to 200 MB), valid for at least 5 minutes.
A finished job gives you text, segments and speakers.
A finished job has text, segments and diarization. Each segment has a speaker role (Agent, Customer or Other), a speaker_id like spk0, start and end in seconds, and the text as spoken:
{
"speaker": "Customer",
"speaker_id": "spk1",
"start": 7.21,
"end": 11.32,
"text": "yes tell me I wanted to ask about the BBA course fees"
}
Roles are guessed and can be wrong, so group lines by speaker_id. On an agent-customer call the agent is spk0. Ringing, caller tunes and hold music are silenced before transcription and listed in diarization.non_speech. Send words: true for word timings.
These are the errors a transcription job can return.
transcription_failed: check the file plays and has speech. WAV and MP3 always work.audio_too_long: it’s over 2 hours. Split it.engine_restarted,job_lost,timed_outorsubmit_interrupted: it broke on our side. Submit again; failed jobs are free.degraded: true: the merge failed and you got the best single pass, free. Resend with a newIdempotency-Keyfor the full one.413 request_too_large: over 45 MB uploaded, or 200 MB linked. Send a link, or split it.429 at_capacity: 20 jobs still running. Wait forRetry-After(30 seconds).429 rate_limited: 120 new jobs in the past hour, or too many requests. Polling counts too.402 insufficient_balance: top up and retry with the sameIdempotency-Key.- The second language reads worse, like a Hindi greeting in an English call: add
contextandvocabulary.
Transcription keys never expire. Reuse one and you get the original job back, even with a different file, so build keys from your recording IDs. There’s no delete endpoint yet.
Transcription costs the same on every plan.
₹18 an hour of audio on every plan, so a 23-second call costs ₹0.12. Each charge is one wallet transaction with kind: "transcription" and the job ID as its reference. The pricing guide covers the other APIs.
Want the whole phone agent, not just the transcript? Agents cost ₹1 a minute on our volume plan; see AI calling.
Sources
These are the references this guide is built on.
References reviewed on . Measurement dates and experimental limits are stated in the article. Check current API and runtime documentation when integrating.
- docs.miraiminds.co
- Transcribe recorded calls
- docs.miraiminds.co
- Transcriptions API reference
- docs.miraiminds.co
- Call transcripts
- docs.miraiminds.co
- Limits and data retention
- huggingface.co
- RinggAI Hindi ASR benchmarking dataset
Questions
These are the questions developers ask us most.
Is there a streaming Hindi speech-to-text API?
It runs inside every voice agent and Realtime session, which send the caller's words as they speak. As a standalone API it's in private preview, so ask us for access.
How much does transcription cost?
₹18 an hour of audio, charged when the job completes, to the millisecond, rounded up to the paisa. A five-minute call costs ₹1.50. Degraded and failed jobs are free. Prices exclude GST.
How accurate is Fourier STT on Hindi?
Fourier STT, our own Hindi speech recognition, scored 9.12% normalised word error rate on all 10,000 utterances of the RinggAI Hindi benchmark. That's read speech, not phone calls, and it isn't the best on every subset, so test with your own audio.
Does the transcript translate Hinglish into Hindi or English?
No. Hindi comes back in Devanagari and English in Latin script, as spoken, though common English loanwords can stay in Devanagari.
Do you keep my audio?
No. An upload passes through a temporary file deleted when the request ends, and a link is fetched once. We keep the transcript, with no published retention period, so copy it to your own storage.
Still deciding? Ask us.
Fifteen minutes with the team that builds it. Bring your script, or your hardest call.
Book 15 minutes