Skip to content

Samples

GET /v1/media/samples lists one sample clip per speech and transcription model; no key needed.

/v1/media/samples serves one sample clip per speech and transcription model, made through the Albastov API. Both routes need no key. Every cloning model speaks the sample line in the shared synthetic voice vo_hVAiUiqrYyvgKKkBvgzHnh, kokoro speaks the line in its built-in voice af_heart, and parakeet transcribes the clip of the shared voice.

List samples

GET /v1/media/samples returns the sample line and the newest sample of each model, recommended models first.

Headers

NameDescription
Cache-ControlResponse. public, max-age=60

Request

curl

curl https://api.albastov.com/v1/media/samples

Python

import json
import urllib.request

with urllib.request.urlopen(urllib.request.Request("https://api.albastov.com/v1/media/samples", headers={"User-Agent": "my-app/1.0"}), timeout=30) as res:
    samples = json.load(res)
print(samples["text"])
for s in samples["samples"]:
    print(s["model"], s["duration_s"], s["url"])

JavaScript

const res = await fetch("https://api.albastov.com/v1/media/samples");
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
const { text, samples } = await res.json();
console.log(text);
for (const s of samples) console.log(s.model, s.duration_s, s.url);

Response

Response
{
  "text": "The river bends past the old mill, where a narrow footbridge crosses to the orchard on the far bank, and the path climbs gently into the hills.",
  "samples": [
    {
      "model": "omnivoice",
      "url": "https://api.albastov.com/v1/media/samples/omnivoice-0c943a261a69d4ec.mp3",
      "content_type": "audio/mpeg",
      "bytes": 123692,
      "duration_s": 7.66,
      "gen_s": 6.3,
      "voice": "vo_hVAiUiqrYyvgKKkBvgzHnh",
      "created_at": "2026-11-01T04:00:48.067Z"
    },
    {
      "model": "parakeet",
      "url": "https://api.albastov.com/v1/media/samples/parakeet-7d74d019c0b0b3c7.mp3",
      "content_type": "audio/mpeg",
      "bytes": 228140,
      "duration_s": 14.26,
      "gen_s": 4.06,
      "voice": "vo_hVAiUiqrYyvgKKkBvgzHnh",
      "created_at": "2026-11-01T04:04:31.261Z",
      "transcript": "Morning light reached the harbour slowly. A cargo ship waited by the pier while gulls circled above the cranes. On the quay a clerk checked the last list of crates, folded it twice, and walked back toward the office as the tide began to turn."
    }
  ]
}

The response above is shortened to two samples.

FieldValue
textThe line every speech model speaks
samples[].modelThe model id
samples[].urlThe clip; the file name carries the file's hash, so a new sample gets a new URL
samples[].content_type, bytes, duration_sThe clip's type, size and length in seconds
samples[].gen_sSeconds the model took to make the sample
samples[].voiceThe voice the model spoke in; for a transcription model, the voice of the transcribed clip
samples[].transcriptThe transcript, on transcription models only
samples[].created_atRFC 3339 time

A model that leaves the model list keeps its sample in the list, after the current models.

Get a sample file

GET /v1/media/samples/{file} returns one sample clip.

Parameters

NameTypeDescription
file requiredstringThe file name from samples[].url, such as kokoro-486457742609d56d.mp3, in the path

Headers

NameDescription
RangeRequest. A byte range, such as bytes=0-1023; the answer is 206 with Content-Range
Content-TypeResponse. The clip's audio type, such as audio/mpeg
Cache-ControlResponse. public, max-age=31536000, immutable

Request

A sample's file name changes when the sample is made again. The example reads the current Kokoro sample's URL from the list, then downloads the file.

curl

URL=$(curl https://api.albastov.com/v1/media/samples \
  | python3 -c 'import json, sys; print(next(s["url"] for s in json.load(sys.stdin)["samples"] if s["model"] == "kokoro"))')

curl "$URL" --output kokoro.mp3

Python

import json
import urllib.request

with urllib.request.urlopen(urllib.request.Request("https://api.albastov.com/v1/media/samples", headers={"User-Agent": "my-app/1.0"}), timeout=30) as res:
    url = next(s["url"] for s in json.load(res)["samples"] if s["model"] == "kokoro")
with urllib.request.urlopen(urllib.request.Request(url, headers={"User-Agent": "my-app/1.0"}), timeout=30) as res, open("kokoro.mp3", "wb") as f:
    f.write(res.read())

JavaScript

import { writeFile } from "node:fs/promises";

const list = await (await fetch("https://api.albastov.com/v1/media/samples")).json();
const { url } = list.samples.find((s) => s.model === "kokoro");
const res = await fetch(url);
if (!res.ok) throw new Error(`${res.status} ${await res.text()}`);
await writeFile("kokoro.mp3", Buffer.from(await res.arrayBuffer()));

Response

200 with the clip as the body; 206 for a byte range.

Errors

StatusCodeMeaning
404not_foundNo sample with the file name