Use this file to discover all available pages before exploring further.
If your product lets users pick a voice, you’ll want to render a searchable list with audio previews. The Supertone API supports this directly: search_voices returns voices that match your filters along with pre-rendered sample clips you can play in the browser.
import osfrom supertone import Supertonewith Supertone(api_key=os.environ["SUPERTONE_API_KEY"]) as client: result = client.voices.search_voices( language="en,ko", style="happy,neutral", gender="female", age="young-adult", page_size=20, ) for voice in result.items or []: sample = next( (s for s in (voice.samples or []) if s.language == "en"), None, ) print(f"{voice.voice_id}\t{voice.name}\t{sample.url if sample else '(no en sample)'}")
If you’re showing voices in a web UI, fetch the list from your backend (never call the Supertone API directly from the browser with your key), then render the sample URLs as <audio> elements.
<!-- After your backend returns the search result as JSON --><ul id="voice-picker"></ul><script> async function renderVoices() { const res = await fetch("/api/voices?language=en&style=happy"); const { items } = await res.json(); const ul = document.getElementById("voice-picker"); for (const voice of items) { const sample = voice.samples?.find((s) => s.language === "en"); const li = document.createElement("li"); li.innerHTML = ` <button data-voice-id="${voice.voiceId}">${voice.name}</button> ${sample ? `<audio controls src="${sample.url}"></audio>` : ""} `; ul.appendChild(li); } } renderVoices();</script>
Tip: the samples field is keyed by (language, style, model) — pick the sample that matches the combination your app actually uses, so the preview matches production output.
search_voices returns up to page_size voices (default 20, max 100) plus a next_page_token if there are more. Pass that token back to fetch the next page:
Python
TypeScript
page = client.voices.search_voices(language="en", page_size=50)while True: for voice in page.items or []: handle(voice) if not page.next_page_token: break page = client.voices.search_voices( language="en", page_size=50, next_page_token=page.next_page_token, )
let page = await client.voices.searchVoices({ language: "en", pageSize: 50 });while (true) { for (const voice of page.items ?? []) { handle(voice); } if (!page.nextPageToken) break; page = await client.voices.searchVoices({ language: "en", pageSize: 50, nextPageToken: page.nextPageToken, });}
Multiple values are OR-ed.language=ko,en returns voices that support either. Use multiple filters together for AND-style narrowing.
No sort parameter. Results come back in their natural order; if you need custom ordering, sort client-side.
Cache responses. The voice library doesn’t change often. Cache lists in your backend (15–60 minutes is reasonable) to reduce calls and improve picker latency.