Transcription Options
Request Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
file |
file | Yes | Audio or video file to transcribe |
model_id |
string | Yes | scribe_v2 for general batch transcription or scribe_v2_medical for medical and clinical audio |
token |
string | No | Single-use authentication token from POST /v1/single-use-token/batch_scribe. Alternative to API key or bearer authentication for frontend clients; expires after 15 minutes and is consumed on use. |
language_code |
string | No | Language hint (ISO 639-1 or ISO 639-3, e.g., en or eng) |
transcript_edit |
string | No | Natural-language instruction applied to the final transcript (maximum 2,000 characters). Cannot be combined with entity_detection, entity_redaction, or use_multi_channel. Adds a 30% surcharge, billed for at least 10 seconds of audio. |
timestamps_granularity |
string | No | none, word, or character (default: word) |
diarize |
boolean | No | Enable speaker diarization (default: false; up to 32 speakers) |
use_speaker_library |
boolean | No | Match diarized speakers against registered speaker profiles in the workspace speaker library. Requires diarize=true |
detect_speaker_roles |
boolean | No | Label diarized speakers as agent and customer instead of speaker_0, speaker_1, etc. Requires diarize=true and cannot be used with use_multi_channel=true |
num_speakers |
integer | No | Maximum speakers to detect (up to 32 for batch) |
diarization_threshold |
number | No | Tune diarization sensitivity (default: ~0.22; only when diarize=true and num_speakers is not set) |
keyterms |
array | No | Terms to bias transcription (up to 100 terms; each ≤50 chars, ≤5 words) |
tag_audio_events |
boolean | No | Detect non-speech sounds like laughter, applause (default: true) |
entity_detection |
string or array | No | Detect entities (e.g., pii, phi, pci, offensive_language) |
no_verbatim |
boolean | No | If true, removes filler words, false starts, and non-speech sounds (supported with scribe_v2) |
use_multi_channel |
boolean | No | Split multichannel audio into separate transcripts (default: false; max 5 channels, max 1 hour) |
multichannel_output_style |
string | No | separate (default) returns one transcript per channel under transcripts; combined returns one merged transcript sorted by word start time with channel_index on each word. Requires timestamps and is only used with use_multi_channel=true |
cloud_storage_url |
string | No | HTTPS URL to transcribe instead of uploading a file (max 2GB) |
source_url |
string | No | URL of an audio or video file to transcribe, including hosted media, YouTube, TikTok, and other video services |
webhook |
boolean | No | Process async and send result to webhook (default: false) |
webhook_id |
string | No | Target specific webhook (only when webhook=true) |
webhook_metadata |
string or object | No | Custom metadata included in webhook responses (max 16KB) |
temperature |
double | No | Output randomness (0.0-2.0); defaults vary by model |
seed |
integer | No | Deterministic output (0-2147483647); same seed = same result |
additional_formats |
array | No | Export transcript as docx, html, pdf, srt, txt, or segmented_json |
file_format |
string | No | pcm_s16le_16 (for lower latency) or other (default) |
enable_logging |
boolean | No | Set false for zero retention mode (enterprise only; default: true) |
Single-Use Token Authentication
Generate a batch Scribe token on a trusted backend, then pass it as the token query parameter
from the frontend. Do not expose the API key to the client.
TOKEN=$(elevenlabs tokens single-use create --token-type batch_scribe --query token --format raw)
elevenlabs speech-to-text convert \
--file audio.mp3 \
--model-id scribe_v2 \
--token "$TOKEN"Python Example
from elevenlabs import ElevenLabs
client = ElevenLabs()
with open("audio.mp3", "rb") as audio_file:
result = client.speech_to_text.convert(
file=audio_file,
model_id="scribe_v2",
language_code="eng",
timestamps_granularity="word",
diarize=True,
keyterms=["ElevenLabs", "Scribe"]
)JavaScript Example
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { createReadStream } from "fs";
const client = new ElevenLabsClient();
const result = await client.speechToText.convert({
file: createReadStream("audio.mp3"),
modelId: "scribe_v2",
languageCode: "eng",
timestampsGranularity: "word",
diarize: true,
keyterms: ["ElevenLabs", "Scribe"],
});CLI Example
elevenlabs speech-to-text convert \
--file audio.mp3 \
--model-id scribe_v2 \
--language-code eng \
--timestamps-granularity word \
--diarize trueAgent and Customer Role Detection
Use detect_speaker_roles with diarization when you want speaker labels tailored for contact center recordings:
Python
result = client.speech_to_text.convert(
file=audio_file,
model_id="scribe_v2",
diarize=True,
detect_speaker_roles=True
)
for word in result.words:
print(f"[{word.speaker_id}] {word.text}")JavaScript
const result = await client.speechToText.convert({
file: createReadStream("call.mp3"),
modelId: "scribe_v2",
diarize: true,
detectSpeakerRoles: true,
});
for (const word of result.words ?? []) {
console.log(`[${word.speakerId}] ${word.text}`);
}CLI
elevenlabs speech-to-text convert \
--file call.mp3 \
--model-id scribe_v2 \
--diarize true \
--detect-speaker-roles true \
--use-speaker-library trueCloud Storage URL
If your media is already stored remotely and accessible over HTTPS, use cloud_storage_url
instead of uploading a local file:
result = client.speech_to_text.convert(
cloud_storage_url="https://storage.example.com/audio.mp3?signature=abc123",
model_id="scribe_v2"
)Transcribing from a URL
Use source_url when the media is already hosted online and you do not want to upload a file directly.
Python
result = client.speech_to_text.convert(
model_id="scribe_v2",
source_url="https://example.com/interview.mp4",
)JavaScript
const result = await client.speechToText.convert({
modelId: "scribe_v2",
sourceUrl: "https://example.com/interview.mp4",
});CLI
elevenlabs speech-to-text convert \
--model-id scribe_v2 \
--source-url "https://www.youtube.com/watch?v=dQw4w9WgXcQ"Response Structure
{
"text": "The complete transcribed text from the audio file.",
"language_code": "eng",
"language_probability": 0.98,
"audio_duration_secs": 12.4,
"words": [
{
"text": "The",
"start": 0.0,
"end": 0.15,
"type": "word",
"speaker_id": "speaker_0"
},
{
"text": " ",
"start": 0.15,
"end": 0.16,
"type": "spacing",
"speaker_id": "speaker_0"
}
]
}Response Fields
| Field | Type | Description |
|---|---|---|
text |
string | Full transcription text |
language_code |
string | Detected language (ISO 639-1 or ISO 639-3) |
language_probability |
float | Confidence in detection (0-1) |
audio_duration_secs |
float | Duration of the transcribed audio in seconds |
words |
array | Word-level timestamps (if requested) |
words[].text |
string | The transcribed word or spacing |
words[].start |
float | Start time in seconds |
words[].end |
float | End time in seconds |
words[].type |
string | word, spacing, or audio_event |
words[].speaker_id |
string | Speaker identifier (if diarization enabled) |
words[].channel_index |
integer or null | Channel index for multichannel audio; null for single-channel transcriptions |
transcription_id |
string | Unique identifier for this transcription |
additional_formats |
array | Exported transcript formats (if requested) |
entities |
array | Detected entities with text, type, and character offsets (if entity_detection enabled) |
edited_transcript |
object or null | Transcript edit result when transcript_edit is set. A successful result has kind: "transcript" and text; a failed edit has kind: "error", error_type: "edit_failed", and message. |
Supported Languages (90+)
Common languages (ISO 639-3 codes):
| Code | Language | Code | Language |
|---|---|---|---|
eng |
English | jpn |
Japanese |
spa |
Spanish | kor |
Korean |
fra |
French | zho |
Mandarin |
deu |
German | ara |
Arabic |
ita |
Italian | hin |
Hindi |
por |
Portuguese | tur |
Turkish |
nld |
Dutch | swe |
Swedish |
pol |
Polish | dan |
Danish |
rus |
Russian | fin |
Finnish |
Full list: Afrikaans, Amharic, Armenian, Azerbaijani, Belarusian, Bengali, Bosnian, Bulgarian, Burmese, Cantonese, Catalan, Cebuano, Croatian, Czech, Estonian, Filipino, Georgian, Greek, Gujarati, Hausa, Hebrew, Hungarian, Icelandic, Indonesian, Irish, Javanese, Kannada, Kazakh, Khmer, Kyrgyz, Lao, Latvian, Lithuanian, Luxembourgish, Macedonian, Malay, Malayalam, Maltese, Māori, Marathi, Mongolian, Nepali, Norwegian, Odia, Pashto, Persian, Punjabi, Romanian, Serbian, Shona, Sindhi, Slovak, Slovenian, Somali, Swahili, Tamil, Tajik, Telugu, Thai, Ukrainian, Urdu, Uzbek, Vietnamese, Welsh, Wolof, Xhosa, Yoruba, Zulu.
Format Requirements
Audio: MP3, WAV, M4A, FLAC, OGG, WebM, AAC, AIFF, Opus Video: MP4, AVI, MKV, MOV, WMV, FLV, WebM, MPEG, 3GPP
Limits:
- Maximum file size: 5.0GB (file upload) or 2GB (cloud storage URL)
- Maximum duration: 10 hours (standard) or 1 hour (multichannel mode)
Use Cases
Subtitle Generation with Speakers
result = client.speech_to_text.convert(
file=audio_file,
model_id="scribe_v2",
timestamps_granularity="word",
diarize=True
)
# Generate SRT with speaker labels
for i, word in enumerate(result.words, 1):
if word.type == "word":
print(f"[{word.speaker_id}] {word.text} ({word.start:.2f}s)")Meeting Transcription with Custom Terms
with open("meeting.mp3", "rb") as f:
result = client.speech_to_text.convert(
file=f,
model_id="scribe_v2",
diarize=True,
keyterms=["Q4 forecast", "revenue target", "ACME Corp"]
)
# Group by speaker
current_speaker = None
for word in result.words:
if word.type == "word":
if word.speaker_id != current_speaker:
current_speaker = word.speaker_id
print(f"\n[{current_speaker}]:", end=" ")
print(word.text, end="")