Create and manage podcast projects with automatic conversion. The Studio API enables programmatic creation and management of audio projects for podcasts and long-form content.
import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
const client = new ElevenLabsClient({ apiKey: "your-api-key" });
// Access this API via: client.studioCreate and automatically convert podcast project.
/**
* @param request - Podcast script and configuration
* @param requestOptions - Optional request configuration
* @returns Created podcast project
* @throws UnprocessableEntityError if request fails
*/
client.studio.createPodcast(
request: BodyCreatePodcastV1StudioPodcastsPost,
requestOptions?: RequestOptions
): HttpResponsePromise<PodcastProjectResponseModel>;
interface BodyCreatePodcastV1StudioPodcastsPost {
/** Used for moderation. Your workspace must be allowlisted to use this feature. */
safetyIdentifier?: string;
/** The ID of the model to be used for this Studio project, you can query GET /v1/models to list all available models. (REQUIRED) */
modelId: string;
/** The type of podcast to generate. Can be 'conversation', an interaction between two voices, or 'bulletin', a monologue. (REQUIRED) */
mode: BodyCreatePodcastV1StudioPodcastsPostMode;
/** The source content for the Podcast. (REQUIRED) */
source: BodyCreatePodcastV1StudioPodcastsPostSource;
/** Output quality: 'standard' (128kbps 44.1kHz), 'high' (192kbps 44.1kHz), 'ultra' (192kbps 44.1kHz highest quality), 'ultra lossless' (705.6kbps 44.1kHz lossless) */
qualityPreset?: "standard" | "high" | "ultra" | "ultra lossless";
/** Duration scale: 'short' (<3min), 'default' (3-7min), 'long' (>7min) */
durationScale?: "short" | "default" | "long";
/** Language of the Studio project (ISO 639-1 two-letter code) */
language?: string;
/** Intro text that will always be added to the beginning of the podcast */
intro?: string;
/** Outro text that will always be added to the end of the podcast */
outro?: string;
/** Additional instructions prompt for the podcast generation used to adjust style and tone */
instructionsPrompt?: string;
/** Brief summary or highlights of the project's content (10-70 characters each) */
highlights?: string[];
/** Webhook URL called when the Studio project is converted */
callbackUrl?: string;
/** Text normalization mode: 'auto', 'on', 'off', 'apply_english' */
applyTextNormalization?: "auto" | "on" | "off" | "apply_english";
}
/** Mode for podcast generation */
interface BodyCreatePodcastV1StudioPodcastsPostMode {
/** Type of podcast: 'conversation' or 'bulletin' */
type: "conversation" | "bulletin";
/** Configuration for conversation mode (required if type is 'conversation') */
conversation?: {
hostVoiceId: string;
guestVoiceId: string;
};
/** Configuration for bulletin mode (required if type is 'bulletin') */
bulletin?: {
voiceId: string;
};
}
/** Source content for the podcast */
interface BodyCreatePodcastV1StudioPodcastsPostSource {
/** Source type: 'text', 'url', or 'file' */
type: "text" | "url" | "file";
/** Text content (required if type is 'text') */
text?: string;
/** URL to extract content from (required if type is 'url') */
url?: string;
/** File to extract content from (required if type is 'file') */
file?: File;
}
interface PodcastProjectResponseModel {
/** Project ID */
project_id: string;
/** Project name */
name: string;
/** Project status */
status: "creating" | "converting" | "completed" | "failed";
/** Audio URL (when completed) */
audio_url?: string;
/** Error message (if failed) */
error?: string;
}Manage Studio projects.
/**
* List all Studio projects
*/
client.studio.projects.list(
request?: ProjectsListRequest,
requestOptions?: RequestOptions
): HttpResponsePromise<GetStudioProjectsResponseModel>;
/**
* Get project details
*/
client.studio.projects.get(
project_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<StudioProjectResponseModel>;
/**
* Update project
*/
client.studio.projects.update(
project_id: string,
request: UpdateStudioProjectRequest,
requestOptions?: RequestOptions
): HttpResponsePromise<StudioProjectResponseModel>;
/**
* Create project
*/
client.studio.projects.create(
request: BodyCreateStudioProjectV1StudioProjectsPost,
requestOptions?: RequestOptions
): HttpResponsePromise<AddProjectResponseModel>;
/**
* Delete project
*/
client.studio.projects.delete(
project_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<void>;
/**
* Convert project to audio
*/
client.studio.projects.convert(
project_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<ConvertProjectResponseModel>;
interface ProjectsListRequest {
page_size?: number;
next_page_token?: string;
status?: "creating" | "converting" | "completed" | "failed";
}
interface StudioProjectResponseModel {
project_id: string;
name: string;
status: string;
created_at: number;
updated_at: number;
audio_url?: string;
duration_seconds?: number;
character_count?: number;
}
interface ConvertProjectResponseModel {
/** Status of conversion request ('ok' if successful) */
status: string;
}Update Studio project content from URL, document, or raw content.
/**
* @param project_id - Project ID
* @param request - Content update options
* @param requestOptions - Optional request configuration
* @returns Updated project
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.content.update(
project_id: string,
request: BodyUpdateStudioProjectContentV1StudioProjectsProjectIdContentPost,
requestOptions?: RequestOptions
): HttpResponsePromise<EditProjectResponseModel>;
interface BodyUpdateStudioProjectContentV1StudioProjectsProjectIdContentPost {
/** URL from which to extract content */
from_url?: string;
/** Document file (.epub, .pdf, .txt, etc.) */
from_document?: File;
/** Raw JSON content */
from_content_json?: string;
/** Whether to auto convert project to audio */
auto_convert?: boolean;
}
interface EditProjectResponseModel {
project: ProjectResponse;
}Manage pronunciation dictionaries for projects.
/**
* @param project_id - Project ID
* @param request - Dictionary locators
* @param requestOptions - Optional request configuration
* @returns Creation status
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.pronunciationDictionaries.create(
project_id: string,
request: BodyCreatePronunciationDictionariesV1StudioProjectsProjectIdPronunciationDictionariesPost,
requestOptions?: RequestOptions
): HttpResponsePromise<CreatePronunciationDictionaryResponseModel>;
interface BodyCreatePronunciationDictionariesV1StudioProjectsProjectIdPronunciationDictionariesPost {
/** List of pronunciation dictionary locators */
pronunciation_dictionary_locators: PronunciationDictionaryVersionLocator[];
/** Auto-mark affected text for reconversion */
invalidate_affected_text?: boolean;
}
interface CreatePronunciationDictionaryResponseModel {
/** Status of request ('ok' if successful) */
status: string;
}Manage chapters within Studio projects.
/**
* @param project_id - Project ID
* @param requestOptions - Optional request configuration
* @returns List of chapters
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.chapters.list(
project_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<GetChaptersResponse>;
interface GetChaptersResponse {
chapters: ChapterResponse[];
}/**
* @param project_id - Project ID
* @param request - Chapter details
* @param requestOptions - Optional request configuration
* @returns Created chapter
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.chapters.create(
project_id: string,
request: BodyCreateChapterV1StudioProjectsProjectIdChaptersPost,
requestOptions?: RequestOptions
): HttpResponsePromise<AddChapterResponseModel>;
interface BodyCreateChapterV1StudioProjectsProjectIdChaptersPost {
/** Chapter name */
name: string;
/** Optional URL to extract content from */
from_url?: string;
}
interface AddChapterResponseModel {
chapter: ChapterWithContentResponseModel;
}/**
* @param project_id - Project ID
* @param chapter_id - Chapter ID
* @param requestOptions - Optional request configuration
* @returns Chapter details with content
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.chapters.get(
project_id: string,
chapter_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<ChapterWithContentResponseModel>;
interface ChapterWithContentResponseModel {
chapter_id: string;
name: string;
last_conversion_date_unix?: number;
conversion_progress?: number;
can_be_downloaded: boolean;
state: string;
has_video?: boolean;
voice_ids?: string[];
statistics?: ChapterStatisticsResponse;
last_conversion_error?: string;
content: ChapterContentResponseModel;
}/**
* @param project_id - Project ID
* @param chapter_id - Chapter ID
* @param request - Chapter updates
* @param requestOptions - Optional request configuration
* @returns Updated chapter
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.chapters.update(
project_id: string,
chapter_id: string,
request?: BodyUpdateChapterV1StudioProjectsProjectIdChaptersChapterIdPost,
requestOptions?: RequestOptions
): HttpResponsePromise<EditChapterResponseModel>;
interface BodyUpdateChapterV1StudioProjectsProjectIdChaptersChapterIdPost {
/** Chapter name */
name?: string;
/** Chapter content */
content?: ChapterContentInputModel;
}
interface EditChapterResponseModel {
chapter: ChapterWithContentResponseModel;
}/**
* @param project_id - Project ID
* @param chapter_id - Chapter ID
* @param requestOptions - Optional request configuration
* @returns Deletion status
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.chapters.delete(
project_id: string,
chapter_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<DeleteChapterResponseModel>;
interface DeleteChapterResponseModel {
/** Status of deletion ('ok' if successful) */
status: string;
}/**
* @param project_id - Project ID
* @param chapter_id - Chapter ID
* @param requestOptions - Optional request configuration
* @returns Conversion status
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.chapters.convert(
project_id: string,
chapter_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<ConvertChapterResponseModel>;
interface ConvertChapterResponseModel {
/** Status of conversion ('ok' if successful) */
status: string;
}Manage chapter snapshots (generated after each conversion).
/**
* @param project_id - Project ID
* @param chapter_id - Chapter ID
* @param requestOptions - Optional request configuration
* @returns List of chapter snapshots
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.chapters.snapshots.list(
project_id: string,
chapter_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<ChapterSnapshotsResponse>;
interface ChapterSnapshotsResponse {
snapshots: ChapterSnapshotResponse[];
}/**
* @param project_id - Project ID
* @param chapter_id - Chapter ID
* @param chapter_snapshot_id - Chapter snapshot ID
* @param requestOptions - Optional request configuration
* @returns Chapter snapshot details
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.chapters.snapshots.get(
project_id: string,
chapter_id: string,
chapter_snapshot_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<ChapterSnapshotExtendedResponseModel>;
interface ChapterSnapshotExtendedResponseModel {
chapter_snapshot_id: string;
project_id: string;
chapter_id: string;
created_at_unix: number;
name: string;
character_alignments: CharacterAlignmentModel[];
}/**
* @param project_id - Project ID
* @param chapter_id - Chapter ID
* @param chapter_snapshot_id - Chapter snapshot ID
* @param request - Stream options
* @param requestOptions - Optional request configuration
* @returns Audio stream
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.chapters.snapshots.stream(
project_id: string,
chapter_id: string,
chapter_snapshot_id: string,
request?: BodyStreamChapterAudioV1StudioProjectsProjectIdChaptersChapterIdSnapshotsChapterSnapshotIdStreamPost,
requestOptions?: RequestOptions
): HttpResponsePromise<ReadableStream<Uint8Array>>;
interface BodyStreamChapterAudioV1StudioProjectsProjectIdChaptersChapterIdSnapshotsChapterSnapshotIdStreamPost {
/** Whether to convert audio to mpeg format */
convert_to_mpeg?: boolean;
}Manage project-level snapshots (generated after full project conversion).
/**
* @param project_id - Project ID
* @param requestOptions - Optional request configuration
* @returns List of project snapshots
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.snapshots.list(
project_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<ProjectSnapshotsResponse>;
interface ProjectSnapshotsResponse {
snapshots: ProjectSnapshotResponse[];
}/**
* @param project_id - Project ID
* @param project_snapshot_id - Project snapshot ID
* @param requestOptions - Optional request configuration
* @returns Project snapshot details
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.snapshots.get(
project_id: string,
project_snapshot_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<ProjectSnapshotExtendedResponseModel>;
interface ProjectSnapshotExtendedResponseModel {
project_snapshot_id: string;
project_id: string;
created_at_unix: number;
name: string;
character_alignments: CharacterAlignmentModel[];
audio_duration_secs: number;
}/**
* @param project_id - Project ID
* @param project_snapshot_id - Project snapshot ID
* @param request - Stream options
* @param requestOptions - Optional request configuration
* @returns Audio stream
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.snapshots.stream(
project_id: string,
project_snapshot_id: string,
request?: BodyStreamStudioProjectAudioV1StudioProjectsProjectIdSnapshotsProjectSnapshotIdStreamPost,
requestOptions?: RequestOptions
): HttpResponsePromise<ReadableStream<Uint8Array>>;
interface BodyStreamStudioProjectAudioV1StudioProjectsProjectIdSnapshotsProjectSnapshotIdStreamPost {
/** Whether to convert audio to mpeg format */
convert_to_mpeg?: boolean;
}/**
* @param project_id - Project ID
* @param project_snapshot_id - Project snapshot ID
* @param requestOptions - Optional request configuration
* @returns Compressed archive stream
* @throws UnprocessableEntityError if request fails
*/
client.studio.projects.snapshots.streamArchive(
project_id: string,
project_snapshot_id: string,
requestOptions?: RequestOptions
): HttpResponsePromise<ReadableStream<Uint8Array>>;Complete type definitions for Studio project responses.
/**
* Complete project response with all metadata
*/
interface ProjectResponse {
/** Project ID */
projectId: string;
/** Project name */
name: string;
/** Creation date (Unix timestamp) */
createDateUnix: number;
/** User ID who created the project */
createdByUserId?: string;
/** Default voice ID for titles */
defaultTitleVoiceId: string;
/** Default voice ID for paragraphs */
defaultParagraphVoiceId: string;
/** Default TTS model ID */
defaultModelId: string;
/** Last conversion date (Unix timestamp) */
lastConversionDateUnix?: number;
/** Whether project can be downloaded */
canBeDownloaded: boolean;
/** Project title */
title?: string;
/** Project author */
author?: string;
/** Project description */
description?: string;
/** List of genres */
genres?: string[];
/** Cover image URL */
coverImageUrl?: string;
/** Target audience */
targetAudience?: ProjectResponseModelTargetAudience;
/** Language (ISO 639-1 code) */
language?: string;
/** Content type (e.g., 'Novel', 'Short Story') */
contentType?: string;
/** Original publication date */
originalPublicationDate?: string;
/** Whether contains mature content */
matureContent?: boolean;
/** ISBN number */
isbnNumber?: string;
/** Volume normalization enabled */
volumeNormalization: boolean;
/** Project state */
state: ProjectState;
/** Access level */
accessLevel: ProjectResponseModelAccessLevel;
/** Fiction classification */
fiction?: ProjectResponseModelFiction;
/** Quality check enabled */
qualityCheckOn: boolean;
/** Quality check on bulk convert */
qualityCheckOnWhenBulkConvert: boolean;
/** Creation metadata */
creationMeta?: ProjectCreationMetaResponseModel;
/** Source type */
sourceType?: ProjectResponseModelSourceType;
/** Chapters enabled */
chaptersEnabled?: boolean;
/** Captions enabled */
captionsEnabled?: boolean;
/** Global caption styling */
captionStyle?: CaptionStyleModel;
/** Public share ID */
publicShareId?: string;
/** Aspect ratio */
aspectRatio?: ProjectResponseModelAspectRatio;
}
/**
* Project state enum
*/
enum ProjectState {
CREATING = "creating",
DEFAULT = "default",
CONVERTING = "converting",
IN_QUEUE = "in_queue",
}
/**
* Project target audience
*/
enum ProjectResponseModelTargetAudience {
CHILDREN = "children",
YOUNG_ADULT = "young adult",
ADULT = "adult",
ALL_AGES = "all ages",
}
/**
* Project access level
*/
enum ProjectResponseModelAccessLevel {
PRIVATE = "private",
PUBLIC = "public",
WORKSPACE = "workspace",
}
/**
* Project fiction classification
*/
enum ProjectResponseModelFiction {
FICTION = "fiction",
NON_FICTION = "non-fiction",
}
/**
* Project source type
*/
enum ProjectResponseModelSourceType {
URL = "url",
FILE = "file",
TEXT = "text",
}
/**
* Project aspect ratio
*/
enum ProjectResponseModelAspectRatio {
RATIO_16_9 = "16:9",
RATIO_9_16 = "9:16",
RATIO_1_1 = "1:1",
}
/**
* Project creation metadata
*/
interface ProjectCreationMetaResponseModel {
/** Creation progress (0-1) */
creationProgress: number;
/** Creation status */
status: ProjectCreationMetaResponseModelStatus;
/** Creation action type */
type: ProjectCreationMetaResponseModelType;
}
/**
* Project creation status
*/
enum ProjectCreationMetaResponseModelStatus {
IN_PROGRESS = "in_progress",
COMPLETED = "completed",
FAILED = "failed",
}
/**
* Project creation type
*/
enum ProjectCreationMetaResponseModelType {
FROM_URL = "from_url",
FROM_FILE = "from_file",
FROM_TEXT = "from_text",
}
/**
* Caption style configuration
* Note: CaptionStyleTemplateModel, CaptionStyleSectionAnimationModel, CaptionStyleWordAnimationModel,
* CaptionStyleCharacterAnimationModel, CaptionStyleHorizontalPlacementModel, and
* CaptionStyleVerticalPlacementModel are available via the ElevenLabs namespace.
*/
interface CaptionStyleModel {
/** Caption template */
template?: CaptionStyleTemplateModel;
/** Text font */
textFont?: string;
/** Text scale */
textScale?: number;
/** Text color */
textColor?: string;
/** Text alignment */
textAlign?: CaptionStyleModelTextAlign;
/** Text style */
textStyle?: CaptionStyleModelTextStyle;
/** Text weight */
textWeight?: CaptionStyleModelTextWeight;
/** Background enabled */
backgroundEnabled?: boolean;
/** Background color */
backgroundColor?: string;
/** Background opacity */
backgroundOpacity?: number;
/** Word highlights enabled */
wordHighlightsEnabled?: boolean;
/** Word highlights color */
wordHighlightsColor?: string;
/** Word highlights background */
wordHighlightsBackgroundColor?: string;
/** Word highlights opacity */
wordHighlightsOpacity?: number;
/** Section animation */
sectionAnimation?: CaptionStyleSectionAnimationModel;
/** Word animation */
wordAnimation?: CaptionStyleWordAnimationModel;
/** Character animation */
characterAnimation?: CaptionStyleCharacterAnimationModel;
/** Width percentage */
widthPct?: number;
/** Horizontal placement */
horizontalPlacement?: CaptionStyleHorizontalPlacementModel;
/** Vertical placement */
verticalPlacement?: CaptionStyleVerticalPlacementModel;
/** Auto break enabled */
autoBreakEnabled?: boolean;
/** Max lines per section */
maxLinesPerSection?: number;
/** Max words per line */
maxWordsPerLine?: number;
}
/**
* Caption style text alignment
*/
enum CaptionStyleModelTextAlign {
LEFT = "left",
CENTER = "center",
RIGHT = "right",
}
/**
* Caption style text style
*/
enum CaptionStyleModelTextStyle {
NORMAL = "normal",
ITALIC = "italic",
}
/**
* Caption style text weight
*/
enum CaptionStyleModelTextWeight {
NORMAL = "normal",
BOLD = "bold",
}
/**
* Chapter content response
*/
interface ChapterContentResponseModel {
/** Array of content blocks */
blocks: ChapterContentBlockResponseModel[];
}
/**
* Chapter content block
*/
interface ChapterContentBlockResponseModel {
/** Block ID */
id: string;
/** Block type */
type: string;
/** Block content nodes */
nodes: ChapterContentNodeResponseModel[];
}
/**
* Chapter content node
*/
interface ChapterContentNodeResponseModel {
/** Node ID */
id: string;
/** Node type */
type: string;
/** Node text content */
text?: string;
/** Voice ID for this node */
voiceId?: string;
/** Whether node is excluded from conversion */
excluded?: boolean;
}
/**
* Chapter content input for updates
*/
interface ChapterContentInputModel {
/** Array of content blocks */
blocks: ChapterContentBlockInputModel[];
}
/**
* Chapter content block input
*/
interface ChapterContentBlockInputModel {
/** Block type */
type: string;
/** Block nodes */
nodes: ChapterContentNodeInputModel[];
}
/**
* Chapter content node input
*/
interface ChapterContentNodeInputModel {
/** Node type */
type: string;
/** Node text */
text?: string;
/** Voice ID */
voiceId?: string;
/** Excluded from conversion */
excluded?: boolean;
}
/**
* Chapter response
*/
interface ChapterResponse {
/** Chapter ID */
chapter_id: string;
/** Chapter name */
name: string;
/** Last conversion date */
last_conversion_date_unix?: number;
/** Conversion progress */
conversion_progress?: number;
/** Can be downloaded */
can_be_downloaded: boolean;
/** Chapter state */
state: string;
/** Has video */
has_video?: boolean;
/** Voice IDs used */
voice_ids?: string[];
/** Chapter statistics */
statistics?: ChapterStatisticsResponse;
/** Last conversion error */
last_conversion_error?: string;
}
/**
* Chapter statistics
*/
interface ChapterStatisticsResponse {
/** Character count */
character_count: number;
/** Duration in seconds */
duration_seconds: number;
}
/**
* Chapter with full content
*/
interface ChapterWithContentResponseModel {
/** Chapter ID */
chapter_id: string;
/** Chapter name */
name: string;
/** Last conversion date */
last_conversion_date_unix?: number;
/** Conversion progress */
conversion_progress?: number;
/** Can be downloaded */
can_be_downloaded: boolean;
/** Chapter state */
state: string;
/** Has video */
has_video?: boolean;
/** Voice IDs used */
voice_ids?: string[];
/** Chapter statistics */
statistics?: ChapterStatisticsResponse;
/** Last conversion error */
last_conversion_error?: string;
/** Chapter content */
content: ChapterContentResponseModel;
}
/**
* Chapter snapshot response
*/
interface ChapterSnapshotResponse {
/** Snapshot ID */
chapter_snapshot_id: string;
/** Project ID */
project_id: string;
/** Chapter ID */
chapter_id: string;
/** Creation timestamp */
created_at_unix: number;
/** Snapshot name */
name: string;
}
/**
* Extended chapter snapshot with alignments
*/
interface ChapterSnapshotExtendedResponseModel {
/** Snapshot ID */
chapter_snapshot_id: string;
/** Project ID */
project_id: string;
/** Chapter ID */
chapter_id: string;
/** Creation timestamp */
created_at_unix: number;
/** Snapshot name */
name: string;
/** Character alignments */
character_alignments: CharacterAlignmentModel[];
}
/**
* Project snapshot response
*/
interface ProjectSnapshotResponse {
/** Snapshot ID */
project_snapshot_id: string;
/** Project ID */
project_id: string;
/** Creation timestamp */
created_at_unix: number;
/** Snapshot name */
name: string;
}
/**
* Extended project snapshot with alignments
*/
interface ProjectSnapshotExtendedResponseModel {
/** Snapshot ID */
project_snapshot_id: string;
/** Project ID */
project_id: string;
/** Creation timestamp */
created_at_unix: number;
/** Snapshot name */
name: string;
/** Character alignments */
character_alignments: CharacterAlignmentModel[];
/** Audio duration in seconds */
audio_duration_secs: number;
}
/**
* Character alignment for audio synchronization
*/
interface CharacterAlignmentModel {
/** Character index in text */
character_index: number;
/** Start time in seconds */
start_time_secs: number;
/** End time in seconds */
end_time_secs: number;
}import { ElevenLabsClient } from "@elevenlabs/elevenlabs-js";
const client = new ElevenLabsClient({ apiKey: "your-api-key" });
// Create bulletin podcast (monologue)
const podcast = await client.studio.createPodcast({
modelId: "eleven_multilingual_v2",
mode: {
type: "bulletin",
bulletin: {
voiceId: "narrator-voice-id",
},
},
source: {
type: "text",
text: "Welcome to our podcast! Today we'll be discussing...",
},
});
console.log("Podcast created:", podcast.project_id);
console.log("Status:", podcast.status);// Create conversation podcast (dialogue between two voices)
const podcast = await client.studio.createPodcast({
modelId: "eleven_multilingual_v2",
mode: {
type: "conversation",
conversation: {
hostVoiceId: "host-voice-id",
guestVoiceId: "guest-voice-id",
},
},
source: {
type: "text",
text: `
Welcome to Tech Talk, where we discuss the latest in technology.
Today's topic is artificial intelligence and machine learning.
`,
},
qualityPreset: "high",
durationScale: "default",
});// Wait for podcast to finish converting
async function waitForPodcast(projectId: string): Promise<string> {
while (true) {
const project = await client.studio.projects.get(projectId);
console.log("Status:", project.status);
if (project.status === "completed") {
return project.audio_url!;
} else if (project.status === "failed") {
throw new Error(`Podcast failed: ${project.error}`);
}
// Wait before checking again
await new Promise(resolve => setTimeout(resolve, 5000));
}
}
const audioUrl = await waitForPodcast(podcast.project_id);
console.log("Podcast ready:", audioUrl);// Get all podcast projects
const projects = await client.studio.projects.list({
pageSize: 50,
status: "completed",
});
console.log("Completed Projects:");
for (const project of projects.projects) {
console.log(`${project.name} (${project.project_id})`);
console.log(` Duration: ${project.duration_seconds}s`);
console.log(` Characters: ${project.character_count}`);
}// Update project name
await client.studio.projects.update(podcast.project_id, {
name: "Episode 1: Introduction (Revised)",
});// Delete podcast project
await client.studio.projects.delete(podcast.project_id);
console.log("Project deleted");import { writeFile } from "fs/promises";
// Download completed podcast
const project = await client.studio.projects.get(podcast.project_id);
if (project.audio_url) {
const response = await fetch(project.audio_url);
const audioBuffer = await response.arrayBuffer();
await writeFile("podcast.mp3", Buffer.from(audioBuffer));
console.log("Podcast downloaded");
}// Create multiple podcast episodes
interface Episode {
number: number;
title: string;
script: string;
}
const episodes: Episode[] = [
{
number: 1,
title: "Introduction",
script: "Welcome to episode 1...",
},
{
number: 2,
title: "Getting Started",
script: "In episode 2, we'll cover...",
},
{
number: 3,
title: "Advanced Topics",
script: "Episode 3 dives deep into...",
},
];
async function createPodcastSeries(
seriesName: string,
episodes: Episode[],
voiceId: string
): Promise<void> {
for (const episode of episodes) {
const podcast = await client.studio.createPodcast({
modelId: "eleven_multilingual_v2",
mode: {
type: "bulletin",
bulletin: {
voiceId: voiceId,
},
},
source: {
type: "text",
text: episode.script,
},
});
console.log(`Created Episode ${episode.number}:`, podcast.project_id);
// Wait for conversion
const audioUrl = await waitForPodcast(podcast.project_id);
console.log(`Episode ${episode.number} ready:`, audioUrl);
}
}
await createPodcastSeries("Tech Talk Podcast", episodes, "narrator-voice-id");// Create podcast from URL source
const podcast = await client.studio.createPodcast({
modelId: "eleven_multilingual_v2",
mode: {
type: "bulletin",
bulletin: {
voiceId: "voice-id",
},
},
source: {
type: "url",
url: "https://example.com/article.html",
},
});// Monitor multiple projects
async function monitorProjects(): Promise<void> {
const projects = await client.studio.projects.list({
status: "converting",
});
console.log(`Monitoring ${projects.projects.length} converting projects`);
for (const project of projects.projects) {
console.log(`${project.name}: ${project.status}`);
}
}
// Run periodically
setInterval(monitorProjects, 30000); // Every 30 seconds// Complete podcast creation workflow
async function createAndDownloadPodcast(
script: string,
voiceId: string,
outputPath: string
): Promise<void> {
// 1. Create project
console.log("Creating podcast...");
const podcast = await client.studio.createPodcast({
modelId: "eleven_multilingual_v2",
mode: {
type: "bulletin",
bulletin: {
voiceId: voiceId,
},
},
source: {
type: "text",
text: script,
},
});
// 2. Wait for completion
console.log("Converting...");
const audioUrl = await waitForPodcast(podcast.project_id);
// 3. Download audio
console.log("Downloading...");
const response = await fetch(audioUrl);
const audioBuffer = await response.arrayBuffer();
await writeFile(outputPath, Buffer.from(audioBuffer));
// 4. Get project details
const project = await client.studio.projects.get(podcast.project_id);
console.log("Podcast created successfully!");
console.log(`Duration: ${project.duration_seconds}s`);
console.log(`Characters: ${project.character_count}`);
console.log(`Saved to: ${outputPath}`);
}
await createAndDownloadPodcast(
"Welcome to my podcast...",
"voice-id",
"./podcast.mp3"
);// Handle podcast creation errors
try {
const podcast = await client.studio.createPodcast({
modelId: "eleven_multilingual_v2",
mode: {
type: "bulletin",
bulletin: {
voiceId: "voice-id",
},
},
source: {
type: "text",
text: "Test content",
},
});
const audioUrl = await waitForPodcast(podcast.project_id);
console.log("Success:", audioUrl);
} catch (error) {
console.error("Podcast creation failed:", error);
// Check if project was created
const projects = await client.studio.projects.list();
const failedProject = projects.projects.find(p => p.status === "failed");
if (failedProject) {
console.error("Failed project:", failedProject.error);
}
}// Get all projects with pagination
async function getAllProjects() {
const allProjects = [];
let nextToken: string | undefined;
while (true) {
const page = await client.studio.projects.list({
pageSize: 100,
next_page_token: nextToken,
});
allProjects.push(...page.projects);
if (!page.has_more) break;
nextToken = page.next_page_token;
}
return allProjects;
}
const all = await getAllProjects();
console.log(`Total projects: ${all.length}`);