Skip to content

Samples

GET /v1/media/samples lists the reference clip and one sample clip per text-to-speech model; no key needed.

/v1/media/samples serves the reference clip and one sample clip per text-to-speech model, made through the Albastar API. Both routes need no key. The reference clip is Narrator A, a synthetic voice made with the Kokoro built-in voice af_heart and saved as the shared voice vo_tBeDCRb2byGFjB6HGyQq6a. Every cloning model speaks the sample line in that voice; kokoro speaks the line in its built-in voice af_heart. Transcription models have no samples.

List samples

GET /v1/media/samples returns the sample line, the reference clip and, per text-to-speech model, the newest sample that passed its check, by model id. Each new sample is transcribed, and a sample whose transcript has a word error rate above 10% against its line is not listed; a model without a listed sample is absent.

Headers

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

Request

curl

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

Python

import json
import urllib.request

req = urllib.request.Request(
    "https://api.albastov.com/v1/media/samples",
    headers={"User-Agent": "my-app/1.0"},
)
with urllib.request.urlopen(req, timeout=30) as res:
    samples = json.load(res)
print(samples["reference"]["voice_label"], samples["reference"]["url"])
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 { reference, samples } = await res.json();
console.log(reference.voice_label, reference.url);
for (const s of samples) console.log(s.model, s.duration_s, s.url);

Response

Response
{
  "text": "I found the photos from the lake house. Do you remember that …",
  "reference": {
    "url": "…/v1/media/samples/reference-848c3d555461736a.mp3",
    "text": "Okay, so here's the plan. We land just after sunset, grab …",
    "duration_s": 14.04,
    "voice_label": "Narrator A",
    "voice": "vo_tBeDCRb2byGFjB6HGyQq6a"
  },
  "samples": [
    {
      "model": "kokoro",
      "url": "…/v1/media/samples/kokoro-486457742609d56d.mp3",
      "content_type": "audio/mpeg",
      "bytes": 176684,
      "duration_s": 11.04,
      "voice": "af_heart",
      "text": "I found the photos from the lake house. Do you remember that …",
      "created_at": "2026-11-03T08:12:40.000Z"
    }
  ]
}

The response above is shortened to one sample, each text to its first words, and each url to its path: every url starts with https://api.albastov.com. The whole sample line and the whole reference text, wrapped at 76 characters:

Sample line
I found the photos from the lake house. Do you remember that summer? We
stayed up until three, arguing about the stars, and you swore you'd seen a
comet. I still think it was a plane.
Reference text
Okay, so here's the plan. We land just after sunset, grab the bags, and head
straight for the harbour. If the ferry's late again — and honestly, it
usually is — we'll get dinner by the water and wait it out. Sound good?
FieldValue
textThe line every text-to-speech model speaks in its sample
reference.urlThe reference clip, the voice the cloning models copy
reference.textThe words of the reference clip
reference.duration_sThe reference clip's length in seconds
reference.voice_label, reference.voiceThe reference voice's name and id; the id works as voice on the speech routes
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[].voiceThe voice the model spoke in: reference.voice for a cloning model, a built-in voice name otherwise
samples[].textThe line the clip says
samples[].created_atRFC 3339 time

A sample whose voice equals reference.voice is a clone of the reference clip. A sample made before the current sample line or reference clip keeps its own text and voice until the model's new sample passes its check. A model that leaves the model list keeps its sample in the list.

Get a sample file

GET /v1/media/samples/{file} returns one sample clip, or the reference clip.

Parameters

NameTypeDescription
file requiredstringThe file name from samples[].url or reference.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 -s https://api.albastov.com/v1/media/samples \
  | python3 -c '
import json, sys
samples = json.load(sys.stdin)["samples"]
print(next(s["url"] for s in samples if s["model"] == "kokoro"))')

curl "$URL" --output kokoro.mp3

Python

import json
import urllib.request

HEADERS = {"User-Agent": "my-app/1.0"}

req = urllib.request.Request(
    "https://api.albastov.com/v1/media/samples", headers=HEADERS
)
with urllib.request.urlopen(req, timeout=30) as res:
    samples = json.load(res)["samples"]
url = next(s["url"] for s in samples if s["model"] == "kokoro")

req = urllib.request.Request(url, headers=HEADERS)
with urllib.request.urlopen(req, timeout=30) as res:
    with open("kokoro.mp3", "wb") as f:
        f.write(res.read())

JavaScript

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

const list = await fetch("https://api.albastov.com/v1/media/samples");
if (!list.ok) throw new Error(`${list.status} ${await list.text()}`);
const { samples } = await list.json();
const { url } = 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 or reference clip with the file name