or run

npx @tessl/cli init
Log in

Version

Tile

Overview

Evals

Files

docs

audio

audio-processing.mdrealtime-transcription.mdspeech-to-speech.mdspeech-to-text.mdtext-to-speech.md
index.md
tile.json

dubbing.mddocs/content/

Dubbing

Dub audio and video files into different languages with AI-powered voice synthesis, transcript management, and multi-language support. Perfect for localizing content while maintaining voice characteristics and emotional delivery.

Related Documentation: To retrieve and download completed dubbing audio files, see the History API documentation for accessing generated audio.

Quick Reference

import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";

const client = new ElevenLabsClient({ apiKey: "your-api-key" });
// Access this API via: client.dubbing

Capabilities

Create Dubbing

Dub audio or video file into target language(s).

/**
 * @param request - Media file and dubbing configuration
 * @param requestOptions - Optional request configuration
 * @returns Dubbing job ID and status
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.create(
  request: BodyDubAVideoOrAnAudioFileV1DubbingPost,
  requestOptions?: RequestOptions
): HttpResponsePromise<DoDubbingResponse>;

interface BodyDubAVideoOrAnAudioFileV1DubbingPost {
  /** Audio or video file to dub */
  file?: File | Blob;
  /** Source file URL (alternative to file upload) */
  source_url?: string;
  /** Target language code(s) */
  target_lang: string | string[];
  /** Source language code (optional, auto-detected if not provided) */
  source_lang?: string;
  /** Number of speakers (1-10, optional for auto-detection) */
  num_speakers?: number;
  /** Whether to watermark free-tier dubs */
  watermark?: boolean;
  /** Start time in seconds */
  start_time?: number;
  /** End time in seconds */
  end_time?: number;
  /** Highest resolution output */
  highest_resolution?: boolean;
  /** Whether content is dubbed for video */
  dubbing_studio?: boolean;
}

interface DoDubbingResponse {
  /** Unique dubbing job ID */
  dubbing_id: string;
  /** Expected duration in seconds */
  expected_duration_sec?: number;
}

List Dubbing Projects

List accessible dubbing projects with filtering and pagination.

/**
 * @param request - List filters and pagination
 * @param requestOptions - Optional request configuration
 * @returns Paginated list of dubbing projects
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.list(
  request?: DubbingListRequest,
  requestOptions?: RequestOptions
): HttpResponsePromise<DubbingMetadataPageResponseModel>;

interface DubbingListRequest {
  /** Pagination cursor */
  cursor?: string;
  /** Page size (default: 100) */
  pageSize?: number;
  /** Filter by dubbing status */
  dubbingStatus?: "dubbing" | "dubbed" | "failed";
  /** Filter by creator */
  filterByCreator?: "personal" | "workspace";
  /** Sort field */
  orderBy?: "created_at" | "name";
  /** Sort direction */
  orderDirection?: "ASCENDING" | "DESCENDING";
}

interface DubbingMetadataPageResponseModel {
  /** Array of dubbing projects */
  dubbings: DubbingMetadata[];
  /** Next page cursor */
  next_cursor?: string;
  /** Whether more results exist */
  has_more: boolean;
}

interface DubbingMetadata {
  dubbing_id: string;
  name?: string;
  status: "dubbing" | "dubbed" | "failed";
  target_languages: string[];
  source_language?: string;
  error?: string;
}

Get Dubbing Project

Get metadata for a specific dubbing project.

/**
 * @param dubbing_id - Dubbing project ID
 * @param requestOptions - Optional request configuration
 * @returns Dubbing project metadata
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.get(
  dubbing_id: string,
  requestOptions?: RequestOptions
): HttpResponsePromise<DubbingMetadataResponse>;

interface DubbingMetadataResponse {
  dubbing_id: string;
  name?: string;
  status: "dubbing" | "dubbed" | "failed";
  target_languages: string[];
  source_language: string;
  num_speakers?: number;
  expected_duration_sec?: number;
  time_dubbed_sec?: number;
  error?: string;
}

Delete Dubbing Project

Delete a dubbing project by ID.

/**
 * @param dubbing_id - Dubbing project ID
 * @param requestOptions - Optional request configuration
 * @returns Deletion confirmation
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.delete(
  dubbing_id: string,
  requestOptions?: RequestOptions
): HttpResponsePromise<DeleteDubbingResponseModel>;

interface DeleteDubbingResponseModel {
  success: boolean;
}

Audio Management

Download dubbed audio for specific languages. If the dubbing was edited in Dubbing Studio, use the resource render endpoint instead.

/**
 * Get dubbed audio/video file for a specific language as MP3 or MP4 stream.
 * Note: If edited in Dubbing Studio, use client.dubbing.resource.render() instead.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param language_code - ID of the target language
 * @param requestOptions - Optional request configuration
 * @returns Streamed audio/video file
 * @throws ForbiddenError if not authorized
 * @throws NotFoundError if dubbing not found
 * @throws UnprocessableEntityError if request fails
 * @throws TooEarlyError if dubbing not ready
 */
client.dubbing.audio.get(
  dubbing_id: string,
  language_code: string,
  requestOptions?: RequestOptions
): HttpResponsePromise<ReadableStream<Uint8Array>>;

Transcript Management

Access and manage transcripts for dubbed content in SRT, WEBVTT, or JSON formats.

/**
 * Get transcript for dubbed content in SRT, WEBVTT, or JSON format.
 * Note: JSON format not supported for Dubbing Studio projects.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param language_code - ID of the language (target language or source)
 * @param request - Format options
 * @param requestOptions - Optional request configuration
 * @returns Transcript in requested format (string for SRT/WEBVTT, object for JSON)
 * @throws ForbiddenError if not authorized
 * @throws NotFoundError if dubbing not found
 * @throws UnprocessableEntityError if request fails
 * @throws TooEarlyError if dubbing not ready
 */
client.dubbing.transcript.getTranscriptForDub(
  dubbing_id: string,
  language_code: string,
  request?: TranscriptGetTranscriptForDubRequest,
  requestOptions?: RequestOptions
): HttpResponsePromise<TranscriptGetTranscriptForDubResponse>;

interface TranscriptGetTranscriptForDubRequest {
  /** Format type: "srt", "webvtt", or "json" (json not supported for Dubbing Studio) */
  formatType?: "srt" | "webvtt" | "json";
}

/**
 * Response type varies by format:
 * - For "srt" or "webvtt": string with formatted subtitles
 * - For "json": DubbingTranscriptResponseModel object
 */
type TranscriptGetTranscriptForDubResponse = string | DubbingTranscriptResponseModel;

interface DubbingTranscriptResponseModel {
  /** Transcript text or structured data */
  transcript: string | TranscriptSegment[];
}

interface TranscriptSegment {
  /** Segment text */
  text: string;
  /** Start time in seconds */
  start: number;
  /** End time in seconds */
  end: number;
  /** Speaker ID */
  speaker_id?: number;
}

Resource Management (Dubbing Studio)

Advanced dubbing project resource management for Dubbing Studio projects. These endpoints require dubbingStudio: true when creating the dubbing job.

/**
 * Get complete dubbing resource with all media tracks, segments, and renders.
 * Requires studio enabled.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param requestOptions - Optional request configuration
 * @returns Complete dubbing resource with tracks, segments, and renders
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.get(
  dubbing_id: string,
  requestOptions?: RequestOptions
): HttpResponsePromise<DubbingResource>;

/**
 * Change attribution of segments to a different speaker.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param request - Segment IDs and target speaker
 * @param requestOptions - Optional request configuration
 * @returns Migration response
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.migrateSegments(
  dubbing_id: string,
  request: BodyMoveSegmentsBetweenSpeakersV1DubbingResourceDubbingIdMigrateSegmentsPost,
  requestOptions?: RequestOptions
): HttpResponsePromise<SegmentMigrationResponse>;

/**
 * Regenerate transcriptions for specified segments.
 * Does not automatically regenerate translations or dubs.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param request - List of segment IDs to transcribe
 * @param requestOptions - Optional request configuration
 * @returns Transcription response
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.transcribe(
  dubbing_id: string,
  request: BodyTranscribesSegmentsV1DubbingResourceDubbingIdTranscribePost,
  requestOptions?: RequestOptions
): HttpResponsePromise<SegmentTranscriptionResponse>;

/**
 * Regenerate translations for specified segments and languages.
 * Automatically transcribes missing transcriptions but does not regenerate dubs.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param request - Segments and optional languages to translate
 * @param requestOptions - Optional request configuration
 * @returns Translation response
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.translate(
  dubbing_id: string,
  request: BodyTranslatesAllOrSomeSegmentsAndLanguagesV1DubbingResourceDubbingIdTranslatePost,
  requestOptions?: RequestOptions
): HttpResponsePromise<SegmentTranslationResponse>;

/**
 * Regenerate dubs for specified segments and languages.
 * Automatically transcribes and translates missing content.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param request - Segments and optional languages to dub
 * @param requestOptions - Optional request configuration
 * @returns Dubbing response
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.dub(
  dubbing_id: string,
  request: BodyDubsAllOrSomeSegmentsAndLanguagesV1DubbingResourceDubbingIdDubPost,
  requestOptions?: RequestOptions
): HttpResponsePromise<SegmentDubResponse>;

/**
 * Regenerate output media for a language using latest Studio state.
 * Asynchronous operation - ensure all segments are dubbed before rendering.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param language - Target language code (e.g., 'es') or 'original' for source track
 * @param request - Render configuration
 * @param requestOptions - Optional request configuration
 * @returns Render response with status and render ID
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.render(
  dubbing_id: string,
  language: string,
  request: BodyRenderAudioOrVideoForTheGivenLanguageV1DubbingResourceDubbingIdRenderLanguagePost,
  requestOptions?: RequestOptions
): HttpResponsePromise<DubbingRenderResponseModel>;

interface BodyMoveSegmentsBetweenSpeakersV1DubbingResourceDubbingIdMigrateSegmentsPost {
  /** Array of segment IDs to migrate */
  segmentIds: string[];
  /** ID of target speaker */
  speakerId: string;
}

interface BodyTranscribesSegmentsV1DubbingResourceDubbingIdTranscribePost {
  /** List of segment IDs to transcribe */
  segments: string[];
}

interface BodyTranslatesAllOrSomeSegmentsAndLanguagesV1DubbingResourceDubbingIdTranslatePost {
  /** List of segment IDs to translate */
  segments: string[];
  /** Optional: specific languages to translate (empty = all) */
  languages?: string[];
}

interface BodyDubsAllOrSomeSegmentsAndLanguagesV1DubbingResourceDubbingIdDubPost {
  /** List of segment IDs to dub */
  segments: string[];
  /** Optional: specific languages to dub (empty = all) */
  languages?: string[];
}

interface BodyRenderAudioOrVideoForTheGivenLanguageV1DubbingResourceDubbingIdRenderLanguagePost {
  /** Render type/format */
  renderType: "mp4" | "aac" | "mp3" | "wav" | "aaf" | "tracks_zip" | "clips_zip";
  /** Whether to normalize audio volume */
  normalizeVolume?: boolean;
}

interface SegmentMigrationResponse {
  /** Migration status */
  status: string;
}

interface SegmentTranscriptionResponse {
  /** Operation status */
  status: string;
  /** Task ID for tracking */
  taskId?: string;
}

interface SegmentTranslationResponse {
  /** Operation status */
  status: string;
  /** Task ID for tracking */
  taskId?: string;
}

interface SegmentDubResponse {
  /** Operation status */
  status: string;
  /** Task ID for tracking */
  taskId?: string;
}

interface DubbingRenderResponseModel {
  /** Operation status */
  status: string;
  /** Render ID for tracking */
  renderId?: string;
}

Language Management

Add and manage languages in dubbing projects.

/**
 * Add a language to the dubbing resource
 * @param dubbing_id - ID of the dubbing project
 * @param request - Language configuration
 * @param requestOptions - Optional request configuration
 * @returns Language added response
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.language.add(
  dubbing_id: string,
  request?: BodyAddALanguageToTheResourceV1DubbingResourceDubbingIdLanguagePost,
  requestOptions?: RequestOptions
): HttpResponsePromise<LanguageAddedResponse>;

interface BodyAddALanguageToTheResourceV1DubbingResourceDubbingIdLanguagePost {
  /** Language code to add */
  language?: string;
}

interface LanguageAddedResponse {
  /** Success status */
  success: boolean;
  /** Language code that was added */
  language: string;
}

Segment Management

Update and delete dubbing segments. Note: updating a segment does not automatically regenerate the dub.

/**
 * Update a single segment with new text and/or timing.
 * Does not automatically regenerate the dub - call resource.dub() after updating.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param segment_id - ID of the segment
 * @param language - Language ID
 * @param request - Segment update payload
 * @param requestOptions - Optional request configuration
 * @returns Segment update response
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.segment.update(
  dubbing_id: string,
  segment_id: string,
  language: string,
  request?: SegmentUpdatePayload,
  requestOptions?: RequestOptions
): HttpResponsePromise<SegmentUpdateResponse>;

/**
 * Delete a single segment from the dubbing project.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param segment_id - ID of the segment to delete
 * @param requestOptions - Optional request configuration
 * @returns Segment deletion response
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.segment.delete(
  dubbing_id: string,
  segment_id: string,
  requestOptions?: RequestOptions
): HttpResponsePromise<SegmentDeleteResponse>;

interface SegmentUpdatePayload {
  /** New start time in seconds */
  startTime?: number;
  /** New end time in seconds */
  endTime?: number;
  /** Updated text for the segment */
  text?: string;
}

interface SegmentUpdateResponse {
  /** Success status */
  success: boolean;
  /** Updated segment ID */
  segment_id: string;
}

interface SegmentDeleteResponse {
  /** Success status */
  success: boolean;
  /** Deleted segment ID */
  segment_id: string;
}

Speaker Management

Create, update, and manage speakers in dubbing projects, including voice selection and discovery.

/**
 * Create a new speaker in the dubbing project.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param request - Speaker creation configuration
 * @param requestOptions - Optional request configuration
 * @returns Speaker creation response with speaker ID
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.speaker.create(
  dubbing_id: string,
  request?: BodyCreateANewSpeakerV1DubbingResourceDubbingIdSpeakerPost,
  requestOptions?: RequestOptions
): HttpResponsePromise<SpeakerCreatedResponse>;

/**
 * Update speaker metadata including voice selection and voice settings.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param speaker_id - ID of the speaker
 * @param request - Speaker metadata update
 * @param requestOptions - Optional request configuration
 * @returns Speaker updated response
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.speaker.update(
  dubbing_id: string,
  speaker_id: string,
  request?: BodyUpdateMetadataForASpeakerV1DubbingResourceDubbingIdSpeakerSpeakerIdPatch,
  requestOptions?: RequestOptions
): HttpResponsePromise<SpeakerUpdatedResponse>;

/**
 * Find top 10 similar voices from the voice library for a speaker.
 * Returns voice IDs, names, descriptions, and sample audio URLs.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param speaker_id - ID of the speaker
 * @param requestOptions - Optional request configuration
 * @returns List of 10 similar voices with metadata and sample audio
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.speaker.findSimilarVoices(
  dubbing_id: string,
  speaker_id: string,
  requestOptions?: RequestOptions
): HttpResponsePromise<SimilarVoicesForSpeakerResponse>;

/**
 * Create a new segment for a specific speaker.
 * Does not automatically generate transcripts/translations/audio - creates segment for every available language.
 *
 * @param dubbing_id - ID of the dubbing project
 * @param speaker_id - ID of the speaker
 * @param request - Segment creation configuration
 * @param requestOptions - Optional request configuration
 * @returns Segment creation response
 * @throws UnprocessableEntityError if request fails
 */
client.dubbing.resource.speaker.segment.create(
  dubbing_id: string,
  speaker_id: string,
  request: SegmentCreatePayload,
  requestOptions?: RequestOptions
): HttpResponsePromise<SegmentCreateResponse>;

interface BodyCreateANewSpeakerV1DubbingResourceDubbingIdSpeakerPost {
  /** Name to attribute to speaker */
  speakerName?: string;
  /** Voice library ID or 'track-clone' | 'clip-clone' */
  voiceId?: string;
  /** Voice stability [0.0, 1.0] (default: 0.65) */
  voiceStability?: number;
  /** Voice similarity boost [0.0, 1.0] (default: 1.0) */
  voiceSimilarity?: number;
  /** Voice style [0.0, 1.0] (default: 1.0) */
  voiceStyle?: number;
}

interface BodyUpdateMetadataForASpeakerV1DubbingResourceDubbingIdSpeakerSpeakerIdPatch {
  /** Name to attribute to speaker */
  speakerName?: string;
  /** Voice library ID or 'track-clone' | 'clip-clone' */
  voiceId?: string;
  /** Voice stability [0.0, 1.0] (default: 0.65) */
  voiceStability?: number;
  /** Voice similarity boost [0.0, 1.0] (default: 1.0) */
  voiceSimilarity?: number;
  /** Voice style [0.0, 1.0] (default: 1.0) */
  voiceStyle?: number;
  /** Languages to apply changes to (empty = all languages) */
  languages?: string[];
}

interface SegmentCreatePayload {
  /** Start time in seconds (required) */
  startTime: number;
  /** End time in seconds (required) */
  endTime: number;
  /** Segment text content */
  text?: string;
  /** Language-specific translations */
  translations?: Record<string, string | undefined>;
}

interface SpeakerCreatedResponse {
  /** Success status */
  success: boolean;
  /** Created speaker ID */
  speaker_id: string;
}

interface SpeakerUpdatedResponse {
  /** Success status */
  success: boolean;
  /** Updated speaker ID */
  speaker_id: string;
}

interface SegmentCreateResponse {
  /** Success status */
  success: boolean;
  /** Created segment ID */
  segment_id: string;
}

interface SimilarVoicesForSpeakerResponse {
  /** List of top 10 similar voices */
  voices: Array<{
    voice_id: string;
    name: string;
    description?: string;
    preview_url?: string;
  }>;
}

Dubbing Resource Types

Complete type definitions for dubbing resources and render management.

/**
 * Complete dubbing resource with all media and tracks
 */
interface DubbingResource {
  /** Resource ID */
  id: string;
  /** Resource version */
  version: number;
  /** Source language code */
  sourceLanguage: string;
  /** Target language codes */
  targetLanguages: string[];
  /** Input media reference */
  input: DubbingMediaReference;
  /** Background media reference */
  background?: DubbingMediaReference;
  /** Foreground media reference */
  foreground?: DubbingMediaReference;
  /** Speaker tracks indexed by ID */
  speakerTracks: Record<string, SpeakerTrack>;
  /** Speaker segments indexed by ID */
  speakerSegments: Record<string, SpeakerSegment>;
  /** Renders indexed by ID */
  renders: Record<string, Render>;
}

/**
 * Media reference for dubbing assets
 */
interface DubbingMediaReference {
  /** Media source path */
  src: string;
  /** Content type (MIME type) */
  contentType: string;
  /** Storage bucket name */
  bucketName: string;
  /** Random path slug for security */
  randomPathSlug: string;
  /** Duration in seconds */
  durationSecs: number;
  /** Whether media is audio only */
  isAudio: boolean;
  /** Full URL to media */
  url: string;
}

/**
 * Speaker track configuration
 */
interface SpeakerTrack {
  /** Track ID */
  id: string;
  /** Media reference for track */
  mediaRef: DubbingMediaReference;
  /** Speaker name/identifier */
  speakerName: string;
  /** Voice IDs per language */
  voices: Record<string, string>;
  /** Segment IDs in this track */
  segments: string[];
}

/**
 * Speaker segment with timing and content
 */
interface SpeakerSegment {
  /** Segment ID */
  id: string;
  /** Start time in seconds */
  startTime: number;
  /** End time in seconds */
  endTime: number;
  /** Segment text */
  text: string;
  /** Subtitle frames */
  subtitles: SegmentSubtitleFrame[];
  /** Dubbed versions per language */
  dubs: Record<string, DubbedSegment>;
}

/**
 * Subtitle frame for segment
 */
interface SegmentSubtitleFrame {
  /** Frame start time */
  startTime: number;
  /** Frame end time */
  endTime: number;
  /** Frame text */
  text: string;
}

/**
 * Dubbed segment in target language
 */
interface DubbedSegment {
  /** Dubbed audio reference */
  mediaRef: DubbingMediaReference;
  /** Dubbed text */
  text: string;
  /** Start time in dubbed version */
  startTime: number;
  /** End time in dubbed version */
  endTime: number;
}

/**
 * Render output configuration
 */
interface Render {
  /** Render ID */
  id: string;
  /** Render version */
  version: number;
  /** Target language (if applicable) */
  language?: string;
  /** Render type/format */
  type?: RenderType;
  /** Output media reference */
  mediaRef?: DubbingMediaReference;
  /** Render status */
  status: RenderStatus;
}

/**
 * Render output types
 */
enum RenderType {
  MP4 = "mp4",
  AAC = "aac",
  MP3 = "mp3",
  WAV = "wav",
  AAF = "aaf",
  TRACKS_ZIP = "tracks_zip",
  CLIPS_ZIP = "clips_zip",
}

/**
 * Render processing status
 */
enum RenderStatus {
  COMPLETE = "complete",
  PROCESSING = "processing",
  FAILED = "failed",
}

/**
 * Request for transcribing dubbing resource
 */
interface TranscribeRequestModel {
  /** Force re-transcription */
  force?: boolean;
}

/**
 * Request for translating dubbing resource
 */
interface TranslateRequestModel {
  /** Force re-translation */
  force?: boolean;
}

/**
 * Request for dubbing resource
 */
interface DubRequestModel {
  /** Force re-dubbing */
  force?: boolean;
  /** Voice settings override */
  voiceSettings?: VoiceSettings;
}

/**
 * Request for rendering dubbing output
 */
interface RenderRequestModel {
  /** Render type to generate */
  renderType?: RenderType;
  /** Force re-render */
  force?: boolean;
}

/**
 * Response models for dubbing operations
 */
interface TranscribeResponseModel {
  /** Operation status */
  status: string;
  /** Task ID for tracking */
  taskId?: string;
}

interface TranslateResponseModel {
  /** Operation status */
  status: string;
  /** Task ID for tracking */
  taskId?: string;
}

interface DubResponseModel {
  /** Operation status */
  status: string;
  /** Task ID for tracking */
  taskId?: string;
}

interface RenderResponseModel {
  /** Operation status */
  status: string;
  /** Render ID */
  renderId?: string;
}

interface MigrateSegmentsResponseModel {
  /** Migration status */
  status: string;
}

/**
 * Dubbing resource response from get operation
 */
interface DubbingResourceResponseModel {
  /** The dubbing resource */
  resource: DubbingResource;
}

Usage Examples

Basic Video Dubbing

import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
import { readFile, writeFile } from "fs/promises";

const client = new ElevenLabsClient({ apiKey: "your-api-key" });

// Load video file
const videoFile = await readFile("video.mp4");

// Create dubbing job
const dubbing = await client.dubbing.create({
  file: new File([videoFile], "video.mp4"),
  target_lang: "es", // Spanish
  source_lang: "en", // English (optional)
});

console.log("Dubbing ID:", dubbing.dubbing_id);
console.log("Expected duration:", dubbing.expected_duration_sec, "seconds");

Multi-Language Dubbing

// Dub into multiple languages at once
const dubbing = await client.dubbing.create({
  file: new File([videoFile], "video.mp4"),
  target_lang: ["es", "fr", "de", "it"], // Spanish, French, German, Italian
  source_lang: "en",
  num_speakers: 2, // Specify number of speakers
  highest_resolution: true,
});

Dub from URL

// Dub video from URL instead of uploading
const dubbing = await client.dubbing.create({
  source_url: "https://example.com/video.mp4",
  target_lang: "ja", // Japanese
  watermark: false,
});

Dub Specific Time Range

// Dub only a portion of the video
const dubbing = await client.dubbing.create({
  file: new File([videoFile], "video.mp4"),
  target_lang: "pt", // Portuguese
  start_time: 30, // Start at 30 seconds
  end_time: 120, // End at 2 minutes
});

Monitor Dubbing Progress

// Poll for dubbing completion
async function waitForDubbing(dubbingId: string): Promise<void> {
  while (true) {
    const metadata = await client.dubbing.get(dubbingId);

    console.log("Status:", metadata.status);

    if (metadata.status === "dubbed") {
      console.log("Dubbing complete!");
      console.log("Time dubbed:", metadata.time_dubbed_sec, "seconds");
      return;
    } else if (metadata.status === "failed") {
      throw new Error(`Dubbing failed: ${metadata.error}`);
    }

    // Wait before polling again
    await new Promise(resolve => setTimeout(resolve, 5000));
  }
}

await waitForDubbing(dubbing.dubbing_id);

Download Dubbed Audio

// Download dubbed audio for each language
const dubbingInfo = await client.dubbing.get(dubbing.dubbing_id);

for (const lang of dubbingInfo.target_languages) {
  const audio = await client.dubbing.audio.get(dubbing.dubbing_id, lang);

  // Save to file
  const chunks: Uint8Array[] = [];
  for await (const chunk of audio) {
    chunks.push(chunk);
  }
  const buffer = Buffer.concat(chunks);
  await writeFile(`dubbed_${lang}.mp4`, buffer);

  console.log(`Downloaded ${lang} dubbing`);
}

Get Transcripts

// Get transcript for source language
const sourceTranscript = await client.dubbing.transcript.getTranscriptForDub(
  dubbing.dubbing_id,
  dubbingInfo.source_language
);

// Get transcript for target language
const targetTranscript = await client.dubbing.transcript.getTranscriptForDub(
  dubbing.dubbing_id,
  "es"
);

console.log("Original:", sourceTranscript.transcript);
console.log("Spanish:", targetTranscript.transcript);

Get SRT Subtitles

// Get transcript as SRT subtitle file
const subtitles = await client.dubbing.transcript.getTranscriptForDub(
  dubbing.dubbing_id,
  "es",
  { format_type: "srt" }
);

await writeFile("subtitles_es.srt", subtitles.transcript);

List All Dubbing Projects

// List all dubbing projects
const projects = await client.dubbing.list({
  pageSize: 50,
  dubbingStatus: "dubbed",
  filterByCreator: "personal",
  orderBy: "created_at",
  orderDirection: "DESCENDING",
});

for (const project of projects.dubbings) {
  console.log(`${project.dubbing_id}: ${project.name || "Unnamed"}`);
  console.log(`  Status: ${project.status}`);
  console.log(`  Languages: ${project.target_languages.join(", ")}`);
}

// Paginate through results
let cursor = projects.next_cursor;
while (cursor && projects.has_more) {
  const nextPage = await client.dubbing.list({
    cursor,
    pageSize: 50,
  });

  // Process next page...

  cursor = nextPage.next_cursor;
}

Delete Dubbing Project

// Delete a dubbing project
await client.dubbing.delete(dubbing.dubbing_id);
console.log("Dubbing project deleted");

Complete Dubbing Workflow

async function dubVideo(
  videoPath: string,
  targetLanguages: string[]
): Promise<void> {
  // 1. Upload and create dubbing job
  const videoFile = await readFile(videoPath);
  const dubbing = await client.dubbing.create({
    file: new File([videoFile], videoPath),
    target_lang: targetLanguages,
    source_lang: "en",
    highest_resolution: true,
  });

  console.log("Dubbing job created:", dubbing.dubbing_id);

  // 2. Wait for completion
  await waitForDubbing(dubbing.dubbing_id);

  // 3. Download all dubbed versions
  const info = await client.dubbing.get(dubbing.dubbing_id);

  for (const lang of info.target_languages) {
    // Download audio
    const audio = await client.dubbing.audio.get(dubbing.dubbing_id, lang);
    const chunks = [];
    for await (const chunk of audio) {
      chunks.push(chunk);
    }
    await writeFile(`output_${lang}.mp4`, Buffer.concat(chunks));

    // Download subtitles
    const srt = await client.dubbing.transcript.getTranscriptForDub(
      dubbing.dubbing_id,
      lang,
      { format_type: "srt" }
    );
    await writeFile(`subtitles_${lang}.srt`, srt.transcript);

    console.log(`Saved ${lang} dubbing and subtitles`);
  }
}

await dubVideo("presentation.mp4", ["es", "fr", "de"]);