Seven commercial speech-to-text engines, scored on 90 hours of real physician dictation. A term counts only when the written form is one a clinician would accept: formatting differences count, misspellings do not.
30,017 clinician-validated entities on identical 1,413 files. A term counts only in a written form a clinician would accept.
| # | Model | Provider | Recall | 95% CI | Vs median | Speed | |
|---|---|---|---|---|---|---|---|
| 1 | ElevenLabs Scribe v2 | ElevenLabs | 83.35% | 82.60–84.09 | +2.70 | 20.1× | |
| 2 | OpenAI gpt-transcribe | OpenAI | 81.79% | 80.69–82.77 | +1.14 | 27.2× | |
| 3 | Microsoft MAI-Transcribe 2 | Microsoft | 81.31% | 80.53–82.09 | +0.66 | 94.2× | |
| 4 | Google Gemini 3.5 Transcribe | 80.65% | 79.48–81.77 | ±0.00 | 44.2× | ||
| 5 | Meta Muse Transcribe | Meta | 77.76% | 76.81–78.68 | −2.89 | 6.5× | |
| 6 | Amazon Transcribe Medical | Amazon | 76.70% | 75.87–77.52 | −3.95 | 8.8× | |
| 7 | xAI Grok STT 1.0 | xAI | 66.74% | 65.71–67.77 | −13.91 | 102.4× |
ElevenLabs Scribe v2 leads at 83.35%. OpenAI gpt-transcribe (81.79%) and Microsoft MAI-Transcribe 2 (81.31%) are a statistical tie for second with different characters: gpt-transcribe spells medicine cleanly, while MAI-2 pairs near-top recall with 94× real-time speed. Google's Gemini 3.5 debuts fourth at 80.65%, within the statistical margin of third, takes two categories outright, and needed the fewest corrections in the field. Muse and Amazon fill the middle, and Grok pairs the field's highest speed with its lowest recall.
◆ = best in field · strict scoring. Every model has a weak spot, and no two share the same one.
| Category | Scribe v2 | gpt-transcribe | MAI-2 | Gemini 3.5 | Muse | Amazon Med. | Grok 1.0 |
|---|---|---|---|---|---|---|---|
| Diagnosis | 83.5 | 82.2 | 82.2 | 83.7 ◆ | 79.7 | 78.7 | 69.7 |
| Medication | 77.9 | 76.5 | 78.0 | 76.4 | 70.2 | 83.0 ◆ | 52.5 |
| Vital sign | 75.0 | 78.6 ◆ | 75.4 | 76.0 | 68.4 | 51.1 | 54.8 |
| Lab value | 65.9 | 75.7 | 69.9 | 78.7 ◆ | 72.0 | 66.3 | 52.8 |
| Procedure | 85.8 ◆ | 82.6 | 80.5 | 83.4 | 79.2 | 74.6 | 66.6 |
| Symptom | 90.0 ◆ | 88.4 | 87.0 | 85.3 | 83.1 | 84.7 | 80.0 |
| Anatomy | 84.1 ◆ | 80.7 | 81.6 | 75.3 | 78.1 | 73.9 | 66.9 |
Scribe v2 leads three of seven categories (symptom 90.0%, procedure 85.7%, anatomy 84.0%). Gemini 3.5 takes diagnosis (83.7%) and lab values (78.7%). Amazon owns medications at 83.0% while dropping to 51.1% on vital signs, and gpt-transcribe takes vital signs (78.6%). Grok misses roughly one medication in two. Lab values are the weakest category field-wide, because the judge does not forgive unit and decimal garbles.
Strict micro recall (%) · specialties with ≥20 files · ◆ = best per specialty.
| Specialty | Scribe v2 | gpt-transcribe | MAI-2 | Gemini 3.5 | Muse | Amazon Med. | Grok 1.0 |
|---|---|---|---|---|---|---|---|
| Medical-legal / IME n=507 | 85.8 | 85.8 | 84.2 | 86.0 ◆ | 81.3 | 80.6 | 72.4 |
| Neurology n=191 | 88.9 ◆ | 88.1 | 85.4 | 87.7 | 84.3 | 76.7 | 67.1 |
| Surgery n=189 | 86.5 | 87.7 ◆ | 83.8 | 83.2 | 81.9 | 79.1 | 67.9 |
| Orthopedics n=178 | 65.8 ◆ | 52.0 | 62.4 | 50.4 | 52.1 | 58.7 | 43.0 |
| Psychiatry n=99 | 81.4 | 82.8 ◆ | 80.9 | 81.1 | 79.9 | 80.6 | 68.8 |
| Pulmonology n=91 | 82.4 | 85.0 ◆ | 81.8 | 82.2 | 77.9 | 77.4 | 68.8 |
| Post-acute care n=51 | 88.9 | 89.2 ◆ | 88.3 | 87.5 | 85.6 | 82.8 | 75.2 |
| Cardiology n=27 | 85.2 | 87.6 ◆ | 86.2 | 86.0 | 84.3 | 79.5 | 72.3 |
| Urology n=23 | 87.5 | 89.5 ◆ | 85.2 | 86.9 | 85.6 | 81.6 | 70.5 |
The ranking moves with the specialty. gpt-transcribe takes psychiatry (82.8%), and Gemini 3.5 edges the medical-legal lead (86.0%). Scribe v2 leads neurology (88.9%) and orthopedics (65.8%). Orthopedics remains the hardest major specialty for every model, with a 23-point spread down to Grok's 43.0%.
X = audio seconds processed per API second (log scale) · Y = strict recall · top-right is best.
Grok is fastest at 102× and least accurate. MAI-Transcribe 2 holds the speed-accuracy frontier: 94× real time at 81.28%. Gemini is second fastest at 44.7×. Muse is slowest (6.5×, 28.9 s median), and Amazon's 8.8× includes its asynchronous upload, queue and poll pipeline, which is the latency production users actually experience. Per-file latency (p50 / p95): Scribe v2: 10.8s / 21.4s · gpt-transcribe: 6.6s / 18.3s · MAI-2: 2.1s / 4.4s · Gemini 3.5: 4.0s / 12.2s · Muse: 28.9s / 86.5s · Amazon Med.: 21.4s / 53.4s · Grok 1.0: 1.9s / 4.3s.
On 28.0% of files no model reached 85% recall, and 192 files defeated all seven. The safety chart counts files where a model missed over half the medications or vital signs: Scribe v2 (20.4%) and MAI-2 (20.7%) fail that way least, and Grok does on more than half its files.
A separate risk review classified all 6,425 near-miss renderings by clinical consequence. It does not change any score. It shows what the recall numbers are made of.
Recall percentages treat every error the same. Clinically they are not the same. A dropped decimal turns Eliquis 2.5 mg into a tenfold anticoagulant overdose. A one-syllable slip turns Toradol, an NSAID, into tramadol, an opioid. These misrenderings look plausible on the page, they survive casual review, and several were written by five different models on the same file. Our risk judge classified every near-miss pair: 191 were rated potentially fatal and 1,027 serious. Every engine in the field produced some.
Each pair was rated on a five-level scale. Fatal: acting on the transcript could directly cause life-threatening harm, such as a wrong drug class, an order-of-magnitude dose, or a tripled frequency. Serious: significant clinical harm or a major treatment error is plausible, such as a similar but wrong drug or a lost critical order. Moderate: could mislead care but would likely be caught in context. Minor: a cosmetic deviation a reader recovers instantly. None: clinically equivalent. Across all 6,425 pairs: 191 fatal, 1,027 serious, 1,566 moderate, 2,027 minor, 1,614 none.
| Model | Fatal-risk renderings | Serious-risk renderings |
|---|---|---|
| Microsoft MAI-Transcribe 2 | 19 | 181 |
| ElevenLabs Scribe v2 | 26 | 216 |
| Meta Muse Transcribe | 28 | 218 |
| OpenAI gpt-transcribe | 31 | 155 |
| Google Gemini 3.5 Transcribe | 42 | 174 |
| Amazon Transcribe Medical | 43 | 235 |
| xAI Grok STT 1.0 | 67 | 310 |
516 of the fatal and serious renderings are outright drug-name garbles: one medication becoming another, or becoming a non-word. 444 of those were made by a single model; no other engine made the same mistake on the same audio. A sample of those single-model errors:
| Reference (scribe note) | What the model wrote | Only model to write it | Risk |
|---|---|---|---|
| Cardene drip | codeine drip | MAI-2 | FATAL |
| Mucinex 600 mg one twice daily for seven days | amoxicillin 600 milligrams 1 twice daily for 7 days | Scribe v2 | FATAL |
| diclofenac 75 mg to take twice a day with food | xanax 75 milligrams to take twice a day with food | gpt-transcribe | FATAL |
| Toradol 30 mg | tramadol 30 mg | Amazon | FATAL |
| tramadol | toradol | Muse | FATAL |
| Humalog | hema log | Gemini 3.5 | FATAL |
| hydrochlorothiazide | hydrochloride | Grok | FATAL |
| Vantin 200 mg twice a day | divantin 200 twice a day | MAI-2 | FATAL |
| clindamycin antibiotic solution | ampicillin antibiotic solution | Scribe v2 | FATAL |
| Ceftin 250 mg twice daily for 10 days | septra 250 milligrams twice daily for 10 days | gpt-transcribe | FATAL |
| QVAR 80 mcg two puffs twice a day | quavar 82 puffs twice a day and | Amazon | FATAL |
| doxycycline 100 mg two tablets for 10 days | oxycodone 100 milligrams 2 tablets for 10 days | Muse | FATAL |
| calcium chloride 20 mEq q. day | potassium chloride 20 meq daily | Gemini 3.5 | FATAL |
| Florinef | fluorine | Grok | FATAL |
| 0.5% Marcaine with epinephrine | markane with epinephrine the | MAI-2 | SERIOUS |
| Zoloft 50 mg one and a half tablets everyday | zolpidem 50 milligrams 1 and a half tablets every day | Scribe v2 | FATAL |
| Sinemet 25/100 mg one tablet daily | senna 25 100 1 tablet daily | gpt-transcribe | FATAL |
| lacosamide 100 mg b.i.d. | glucosamide 100 mg b.i.d. | Amazon | FATAL |
Sound-alike drug pairs are a known hazard in human transcription, and each model has its own: a cardiac drip becomes an opioid, an expectorant becomes an antibiotic, an NSAID becomes Xanax. No other engine made the same mistake on the same audio, which makes these model-specific confusions rather than audio problems. Each swap is a different pharmacology delivered to the chart in confident prose.
Real data, clinician-validated ground truth, and a verified scoring pipeline checked for vendor neutrality. Every layer is applied identically to every model.
1,413 scored files (of 1,424 collected): real physician dictations with paired scribe-authored SOAP notes. All of it is dictation audio: a single physician speaking close to the microphone, no crosstalk, no far-field capture. That makes the conditions favorable, and the remaining errors harder to excuse. 90.5 hours, median 3 min 05 s, 14 specialties led by medical-legal/IME (36%), neurology, surgery, orthopedics and psychiatry. The audio is dominated by telephony: 1,003 files (70%) are GSM 6.10-compressed WAV from telephone dictation lines, which carry codec-limited, telephony-band speech. The rest splits between 235 MP3 recordings (44.1 kHz mono, 320 kbps) and 186 uncompressed PCM WAV files (16 kHz). Estimated SNR by the frame-energy percentile method: PCM median 24 dB, MP3 33 dB, GSM 44 dB. The high GSM figure reflects codec noise-squelching, not better speech. Every recording is real data from real clinical environments. Nothing is synthetic, scripted or studio-read. The corpus is part of Appen's licensed dataset library, and only audio never sold to or acquired by any of the companies tested was used, so no model could have seen this data in training.
Every model ran through its standard production interface with vendor-recommended defaults. Runs were checkpointed per file, failures logged and retried, and latency measured as the full API round-trip. Expand a model for the exact request and response shape:
Request (per file):
POST https://api.elevenlabs.io/v1/speech-to-text xi-api-key: **** multipart/form-data: model_id = "scribe_v2" language_code = "en" diarize = "true" timestamps_granularity = "word" tag_audio_events = "false" file = <raw audio bytes>
Response shape:
{"text": "... blood pressure one twenty-six over sixty-two ...", "words": [...], "language_code": "eng"}Request (per file):
POST https://api.openai.com/v1/audio/transcriptions Authorization: Bearer **** multipart/form-data: model = "gpt-transcribe" file = <raw audio bytes> (language auto-detected)
Response shape:
{"text": "... medication like metformin, omeprazole, ... ...", "languages": ["en"], "usage": {...}}Request (per file):
POST {AZURE_ENDPOINT}/speechtotext/transcriptions:transcribe?api-version=2025-10-15
Ocp-Apim-Subscription-Key: ****
multipart/form-data:
definition = {"enhancedMode": {"enabled": true, "model": "mai-transcribe-2",
"transcribeStyle": "verbatim"}, "locales": ["en-US"]}
audio = <raw audio bytes>Response shape:
{"combinedPhrases": [{"text": "... on medication metformin, omeprazole, Invokana, Unglyza, glipizide ..."}]}Request (per file):
google-genai SDK -> models.generate_content model = "gemini-3.5-transcribe" contents = [<audio bytes inline>, "Transcribe this medical dictation verbatim."] (one persistently empty response file excluded from the common subset for all models; see limitations)
Response shape:
{"candidates": [{"content": {"parts": [{"text": "... dictating a monthly follow-up ..."}]}}]}Request (per file):
POST https://api.meta.ai/v1/asr/transcribe?sessionId=<uuid>
Authorization: Bearer ****
multipart/form-data:
request = {"mode": "DIARIZATION", "model": "muse-voice-transcribe-1.0",
"audioEncoding": "WAV"}
audio = <16 kHz mono PCM WAV bytes> (files > 580 s chunked)Response shape:
{"text": "... blood pressure 126 over 62 respirations 18 pulse 74 ...", "segments": [...]}Request (per file):
boto3 (us-east-1): upload to S3, then
StartMedicalTranscriptionJob(
LanguageCode="en-US", Specialty="PRIMARYCARE", Type="DICTATION",
MediaFormat="mp3"|"wav", Media={"MediaFileUri": "s3://<bucket>/<key>"})
poll GetMedicalTranscriptionJob every 5 s -> fetch result JSON from S3Response shape:
{"results": {"transcripts": [{"transcript": "... on medication metformin, omeprazole, Invokana. Onglyza ..."}]}}Request (per file):
POST https://api.x.ai/v1/stt Authorization: Bearer **** multipart/form-data: format = "true" language = "en" file = <raw audio bytes> (NO keyterm parameters; GSM WAV pre-converted to PCM)
Response shape:
{"text": "... blood pressure 126 over 62, respirations 18, pulse 74. ...", "words": [...]}Reference entities were extracted from the scribe notes at temperature 0 and reviewed by a cohort of medical experts, who also spot-checked the final outputs and scores of every model. To score a transcript, entity and transcript first pass through the same clinical normalization: casing and punctuation are unified and spoken numbers canonicalized, so that “126/62”, “126 over 62” and “one twenty-six over sixty-two” are the same blood pressure. Matching then runs exact, fuzzy (indel ≥ 80), and bidirectional abbreviation, in that order.
Character similarity finds near-misses, but it cannot tell a formatting difference from a misspelling: “para vertebral” and “Unglyza” look equally close to their references. So every one of the 12,326 distinct near-miss pairs was reviewed the way a clinician would read it (Gemini 3.8 Flash, temperature 0, fixed policy). A rendering is credited when the written form is one clinicians actually use: spacing and hyphenation differences, recognized alternate spellings, standard abbreviations, equivalent number formats, minor inflections. This is what protects models from being punished for style — a model that writes “b.i.d.” where the note says “twice daily”, or hyphenates a compound term, loses nothing. What gets rejected is substance: misspellings and non-words (“Unglyza” for the drug “Onglyza”), different drugs or structures however similar, and garbles a clinician would flag. 21.2% of pairs were accepted; rejected credits count as misses. Canary checks passed: misspelled brand names rejected, spacing-only variants accepted.
Neutrality is verified rather than assumed. In decoy testing, identical clinical entities from unrelated files produced statistically indistinguishable false-match rates across models (7.6–8.4%), so no model gains an advantage from verbosity or output style. Every model faced identical files, entities, thresholds and judges, with no vocabulary hints, and every recall figure carries a file-level bootstrap 95% CI (2,000 resamples).
Pulmonology follow-up dictated over a telephone line (GSM 6.10 WAV, 21 reference entities; internal id …163350). The scribe note lists the patient's medications, including “gabapentin 300 mg at bedtime … Incruse inhaler daily.” Each model's rendering of that passage, verbatim:
| Model | Rendering of the medication passage |
|---|---|
| Scribe v2 | “Gabapentin three hundred milligrams at bedtime, Qvar inhaler daily, Vent” |
| gpt-transcribe | “gabapentin 300 milligrams at bedtime, Incruse inhaler daily, Ventolin PR” |
| MAI-2 | “gabapentin 300 milligrams at bedtime, Incruse inhaler daily, Ventolin, P” |
| Gemini 3.5 | “gabapentin 300 milligrams at bedtime Incruse Ellipta daily Ventolin PRN” |
| Muse | “gabapentin 300 milligrams at bedtime incruise inhaler daily, Ventolin PR” |
| Amazon Med. | “gabapentin 300 mg at bedtime, Incruse inhaler daily, Ventolin prn and pr” |
| Grok 1.0 | “gabapentin 300 milligrams at bedtime, in-cruz inhaler daily, ventolin PR” |
Scoring of eight representative entities. ✓ credited · ✓f credited via accepted fuzzy match · ✗j near-miss rejected by the judge · ✗ missed:
| Reference entity | Category | Scribe v2 | gpt-transcribe | MAI-2 | Gemini 3.5 | Muse | Amazon Med. | Grok 1.0 |
|---|---|---|---|---|---|---|---|---|
| advanced COPD | diagnosis | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| gabapentin 300 mg at bedtime | medication | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ | ✓ |
| blood pressure 122/84 | vital sign | ✓ | ✓ | ✓ | ✓ | ✓ | ✗ | ✓ |
| heart rate 84 | vital sign | ✗j | ✓ | ✓ | ✗j | ✗j | ✗j | ✗j |
| Incruse inhaler daily | medication | ✗ | ✓ | ✓ | ✗ | ✗j | ✓ | ✗j |
| oxygen saturation is 98.4% on room air | vital sign | ✗j | ✗ | ✗j | ✗j | ✗j | ✗ | ✗j |
| Nasopharynx | anatomy | ✗j | ✓ | ✓ | ✗ | ✗j | ✗ | ✗ |
| oropharynx | anatomy | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ | ✗ |
One inhaler, four fates: Amazon, MAI-2 and gpt-transcribe write “Incruse” and get credit. Grok writes “in-cruz” and Muse writes “incruise”, and the judge rejects both as non-words (✗j). Scribe v2 writes “Qvar”, a different inhaler entirely, and misses. Gemini writes “Incruse Ellipta daily”, which no longer matches the reference phrase and scores as a miss. “Oropharynx” defeats all seven on this recording. Full per-file results and raw API responses are available on request.
Appen builds expert data for the frontier of AI: the specialist, hard-to-reach data that generic web corpora cannot supply. The audio behind MedTerm-90 is a case in point. These are real dictations by real practicing physicians, captured in live clinical transcription workflows and licensed for AI development through Appen's data partnerships. Speech like this cannot be scripted, synthesized, or scraped. That access runs deep: licensed real-world archives across regulated domains, a global network of vetted specialists (clinicians among them) for expert annotation and validation, and coverage across 500+ locales and acoustic conditions. The same machinery powering this benchmark is available to model builders: expert domain corpora from Appen's data library, custom collection with specialist ground truth, and evaluation pipelines like this one run on your own models, your own data, your own metrics.