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

samples.mddocs/voices/

Sample Management

Manage voice samples directly through the samples API. A sample is any audio file attached to a voice. A voice can have one or more samples that define its characteristics.

What are Voice Samples?

Voice samples are audio recordings that define the characteristics of a cloned or custom voice. Each sample contributes to the overall voice profile:

  • Single Sample: Minimum of 1 sample required (quick voice cloning)
  • Multiple Samples: 3-10 samples recommended for higher quality
  • Sample Quality: Clear audio, minimal background noise, 30 seconds to 3 minutes each
  • Sample Diversity: Different emotions, tones, or speaking styles improve versatility

Samples are managed at the voice level through the voices API, but can also be deleted individually using this dedicated samples API.

Quick Reference

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

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

Capabilities

Delete Sample

Remove a specific sample from a voice by its ID.

/**
 * Removes a sample by its ID.
 *
 * @param voice_id - ID of the voice containing the sample
 * @param sample_id - ID of the sample to remove
 * @param requestOptions - Request-specific configuration
 * @returns Delete confirmation response
 * @throws {@link ElevenLabs.UnprocessableEntityError}
 *
 * @example
 *   await client.samples.delete("21m00Tcm4TlvDq8ikWAM", "VW7YKqPnjY4h39yTbx2L")
 */
client.samples.delete(
  voice_id: string,
  sample_id: string,
  requestOptions?: RequestOptions
): HttpResponsePromise<ElevenLabs.DeleteSampleResponse>;

Usage Example:

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

const client = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

// Delete a sample from a voice
const voiceId = "21m00Tcm4TlvDq8ikWAM";
const sampleId = "VW7YKqPnjY4h39yTbx2L";

const result = await client.samples.delete(voiceId, sampleId);
console.log("Sample deleted successfully");

Types

/**
 * Response model for sample deletion
 */
interface DeleteSampleResponse {
  /** Confirmation message */
  message?: string;
}

Related APIs

Sample management is also available through the voices API:

  • Get all samples for a voice: client.voices.get(voiceId)
  • Add samples when creating voices: client.voices.ivc.create() or client.voices.pvc.create()
  • Update voice including samples: client.voices.update()
  • Delete samples: client.samples.delete() (this API) or through voice editing

See Voice Management for comprehensive voice and sample operations.

Workflow Examples

Clean Up Voice Samples

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

const client = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

// Get voice details with all samples
const voice = await client.voices.get("voice-id");

console.log(`Voice "${voice.name}" has ${voice.samples.length} samples`);

// Identify and remove low-quality or unwanted samples
for (const sample of voice.samples) {
  console.log(`Sample: ${sample.sample_id}`);
  console.log(`  Name: ${sample.file_name}`);
  console.log(`  Hash: ${sample.hash}`);

  // Remove sample if needed
  // await client.samples.delete("voice-id", sample.sample_id);
}

Rebuild Voice with Better Samples

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

const client = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

async function rebuildVoice(voiceId: string, newSamplePaths: string[]) {
  // 1. Get current voice
  const voice = await client.voices.get(voiceId);
  console.log(`Rebuilding voice: ${voice.name}`);

  // 2. Delete all existing samples
  console.log(`Removing ${voice.samples.length} existing samples...`);
  for (const sample of voice.samples) {
    await client.samples.delete(voiceId, sample.sample_id);
    console.log(`  Removed sample: ${sample.file_name}`);
  }

  // 3. Add new samples
  console.log(`Adding ${newSamplePaths.length} new samples...`);
  const newSamples = await Promise.all(
    newSamplePaths.map(async (path) => {
      const fileBuffer = await readFile(path);
      return new File([fileBuffer], path.split("/").pop() || "sample.mp3");
    })
  );

  await client.voices.update(voiceId, {
    name: voice.name,
    description: voice.description,
    files: newSamples,
  });

  console.log("Voice rebuilt successfully!");

  // 4. Verify new samples
  const updatedVoice = await client.voices.get(voiceId);
  console.log(`Voice now has ${updatedVoice.samples.length} samples`);
}

// Usage
await rebuildVoice("voice-id", [
  "./samples/sample1.mp3",
  "./samples/sample2.mp3",
  "./samples/sample3.mp3",
]);

Sample Quality Audit

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

const client = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

async function auditVoiceSamples(voiceId: string) {
  const voice = await client.voices.get(voiceId);

  console.log(`\n=== Sample Audit for "${voice.name}" ===\n`);
  console.log(`Total samples: ${voice.samples.length}`);
  console.log(`Recommended: 3-10 samples for optimal quality\n`);

  if (voice.samples.length < 3) {
    console.log("⚠️  Warning: Less than 3 samples. Consider adding more for better quality.");
  } else if (voice.samples.length > 10) {
    console.log("ℹ️  Info: More than 10 samples. Consider removing lower quality samples.");
  } else {
    console.log("✅ Sample count is optimal.");
  }

  console.log("\nSamples:");
  voice.samples.forEach((sample, index) => {
    console.log(`${index + 1}. ${sample.file_name}`);
    console.log(`   ID: ${sample.sample_id}`);
    console.log(`   Hash: ${sample.hash}`);
  });

  return voice;
}

// Audit all voices
const allVoices = await client.voices.getAll();
for (const voice of allVoices.voices) {
  await auditVoiceSamples(voice.voice_id);
}

Batch Sample Removal

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

const client = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

async function removeSamplesByPattern(
  voiceId: string,
  pattern: RegExp
): Promise<number> {
  const voice = await client.voices.get(voiceId);
  let removedCount = 0;

  for (const sample of voice.samples) {
    if (pattern.test(sample.file_name)) {
      await client.samples.delete(voiceId, sample.sample_id);
      console.log(`Removed: ${sample.file_name}`);
      removedCount++;
    }
  }

  return removedCount;
}

// Remove all samples with "test" in the filename
const removed = await removeSamplesByPattern(
  "voice-id",
  /test/i
);
console.log(`Removed ${removed} test samples`);

Sample Backup and Restore

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

const client = new ElevenLabsClient({
  apiKey: process.env.ELEVENLABS_API_KEY,
});

interface VoiceBackup {
  voice_id: string;
  name: string;
  description?: string;
  samples: Array<{
    sample_id: string;
    file_name: string;
    hash: string;
  }>;
}

async function backupVoiceSamples(voiceId: string): Promise<void> {
  const voice = await client.voices.get(voiceId);

  const backup: VoiceBackup = {
    voice_id: voice.voice_id,
    name: voice.name,
    description: voice.description,
    samples: voice.samples.map((s) => ({
      sample_id: s.sample_id,
      file_name: s.file_name,
      hash: s.hash,
    })),
  };

  await writeFile(
    `voice-backup-${voiceId}.json`,
    JSON.stringify(backup, null, 2)
  );

  console.log(`Backed up ${backup.samples.length} samples for "${voice.name}"`);
}

async function listSamplesFromBackup(backupPath: string): Promise<void> {
  const backup: VoiceBackup = JSON.parse(
    await readFile(backupPath, "utf-8")
  );

  console.log(`Backup for voice: ${backup.name}`);
  console.log(`Voice ID: ${backup.voice_id}`);
  console.log(`\nSamples in backup:`);
  backup.samples.forEach((sample, index) => {
    console.log(`${index + 1}. ${sample.file_name} (${sample.sample_id})`);
  });
}

// Backup samples before making changes
await backupVoiceSamples("voice-id");

// Later, review the backup
await listSamplesFromBackup("voice-backup-voice-id.json");

For comprehensive voice management including adding samples, see the Voice Management documentation.