All skills
elevenlabs avatar

/speech-to-text

@279173d official
by elevenlabselevenlabs/skills462 stars
74

Transcribe audio to text using ElevenLabs Scribe v2. Use when converting audio/video to text, generating subtitles, transcribing meetings, or processing spoken content.

Use this Skill: https://skilld.dev/gh/elevenlabs/skills/speech-to-text

This session only. Nothing lands on disk.

referencestranscription-options.md

≈2.7k tokens on demand. Your agent reads this file only when SKILL.md points to it.

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 true

Agent 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 true

Cloud 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="")

Source: SKILL.md on GitHub

2 warnings1d5 checks · Risk SAFE
  • Gen Agent Trust Hub1d

    The skill facilitates audio and video transcription through ElevenLabs Scribe v2. Security analysis identifies a standard indirect prompt injection surface where instructions contained within the audio/video input could influence agent behavior after transcription. All external tools and scripts originate from official vendor repositories.

  • Socket1d

    No alerts

  • Snyk1d

    Risk: MEDIUM · 1 issue

  • Runlayer6mo

    4/7 files flagged

  • ZeroLeaks5mo

    Score: 93/100 · 2 sections analyzed

Signed by skilld at 279173d. This ties the file your Agent reads to that commit on GitHub. It does not review the instructions.

Last checked against GitHub yesterday.

Activeupdated 2 days ago
compatibility
Requires internet access and an ElevenLabs API key (ELEVENLABS_API_KEY).
Other metadata
metadata
{
  "openclaw": {
    "requires": {
      "env": [
        "ELEVENLABS_API_KEY"
      ]
    },
    "primaryEnv": "ELEVENLABS_API_KEY"
  }
}
  • API
  • Python
  • elevenlabs
  • speech-to-text
  • transcription
  • audio
  • diarization
  • timestamps
  • javascript

README badge

README badge for elevenlabs/skills/speech-to-text

Transcribe audio and video to text using ElevenLabs Scribe v2, with support for 90+ languages, speaker diarization, word-level timestamps, and real-time streaming (~150ms latency). Covers batch transcription for meetings and subtitles, live voice agent input, and keyterm prompting for domain-specific vocabulary.

Generated from the current SKILL.md.

Does this skill support real-time transcription?
Yes. Use `scribe_v2_realtime` model for live transcription with ~150ms latency. It supports Voice Activity Detection (VAD) auto-commit or manual commit strategies, and works with both server-side streaming and client-side React components.
What languages does this support?
The skill supports 90+ languages with automatic detection. You can optionally provide a language hint using ISO 639-1 or ISO 639-3 codes.
Does this provide speaker identification?
Yes. Enable `diarize=true` to label each word with a speaker ID. For call recordings, you can also set `detect_speaker_roles=true` to label speakers as `agent` and `customer`.
What file formats and sizes does this handle?
Supports MP3, WAV, M4A, FLAC, OGG, WebM, AAC, AIFF, Opus for audio and MP4, AVI, MKV, MOV, WMV, FLV, WebM, MPEG, 3GPP for video. Maximum file size is 5.0GB with a 10-hour duration limit.
Can I get word-level timing information?
Yes. Set `timestamps_granularity="word"` to get start/end times for each word, plus type classification (word, spacing, audio_event) and speaker identification.

Generated from the current SKILL.md. These answers refresh after source changes.