Skip to main content
ElevenLabs Documentation Docs
current

Search documentation

Type to search this documentation.

On this pageOverview

Transcript editing

This guide shows you how to apply natural-language edit instructions to committed transcripts with the Realtime Speech to Text API.

Realtime transcription can apply a natural-language edit instruction to every committed transcript, for example to write spoken dates in a fixed format or to expand abbreviations and acronyms. The instruction is passed once when the connection is opened, and each committed transcript is followed by a separate edited_transcript event with the edited text.

Partial transcripts are never edited. The committed_transcript event is not changed either, so existing integrations keep working when you turn the feature on.

Pass the instruction with the transcriptEdit option when connecting (the transcript_edit query parameter of the WebSocket API). The instruction can be up to 2000 characters long. See the batch transcript editing guide for guidance on writing instructions.

In all SDKs the edited transcripts arrive through the RealtimeEvents.EDITED_TRANSCRIPT event.

Use @elevenlabs/client in the browser with a single-use token issued by your server, as described in the client-side streaming guide.

TypeScript
import { Scribe, RealtimeEvents } from "@elevenlabs/client";

// Fetch a single-use token from your server first
const response = await fetch("/scribe-token", yourAuthHeaders);
const { token } = await response.json();

const connection = Scribe.connect({
  token,
  modelId: "scribe_v2_realtime",
  transcriptEdit: "Write all dates in ISO 8601 format (YYYY-MM-DD)",
  microphone: {
    echoCancellation: true,
    noiseSuppression: true,
  },
});

connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, (data) => {
  console.log("Committed:", data.text);
});

connection.on(RealtimeEvents.EDITED_TRANSCRIPT, (data) => {
  console.log("Edited:", data.edited_text);
});

Use the official SDK on your server, as described in the server-side streaming guide. Only the option and the event handler differ from that guide; sending audio and closing the connection work the same way.

Python
import asyncio
import os
from dotenv import load_dotenv
from elevenlabs import AudioFormat, ElevenLabs, RealtimeAudioOptions, RealtimeEvents

load_dotenv()

async def main():
    elevenlabs = ElevenLabs(api_key=os.getenv("ELEVENLABS_API_KEY"))

    connection = await elevenlabs.speech_to_text.realtime.connect(RealtimeAudioOptions(
        model_id="scribe_v2_realtime",
        audio_format=AudioFormat.PCM_16000,
        sample_rate=16000,
        transcript_edit="Write all dates in ISO 8601 format (YYYY-MM-DD)",
    ))

    def on_committed_transcript(data):
        print(f"Committed: {data.get('text', '')}")

    def on_edited_transcript(data):
        print(f"Edited: {data.get('edited_text', '')}")

    connection.on(RealtimeEvents.COMMITTED_TRANSCRIPT, on_committed_transcript)
    connection.on(RealtimeEvents.EDITED_TRANSCRIPT, on_edited_transcript)

    # Send audio chunks as shown in the server-side streaming guide, then close.
    await connection.close()

if __name__ == "__main__":
    asyncio.run(main())

When enabled, each committed transcript is followed by an edited_transcript event carrying the committed text and its edited version:

JSON
{
  "message_type": "edited_transcript",
  "text": "our next meeting is on the twelfth of July twenty twenty-six",
  "edited_text": "our next meeting is on 2026-07-12"
}

Behavior to be aware of:

  • Edits are applied per committed segment. The edited_transcript event is emitted shortly after the corresponding committed_transcript event, since editing runs asynchronously. It may arrive after the next partial transcript, and edits for consecutive segments may arrive out of order. Use the text field to match an edit to its committed transcript.
  • If no edits were made to a segment, edited_text is identical to text.
  • If an edit cannot be produced for a segment, no edited_transcript event is sent for it. The committed_transcript event is not affected.
  • Word-level timestamps in committed_transcript_with_timestamps describe the original committed text, not the edited text.
Suggest an edit

Propose a replacement for this page. The site team reviews it before applying any changes.

Export
Documentation menu