Read the Sume TTS Router catalog in one request: Sonic ids, prices
GET /v1/tts-router/models lists the Sonic ids, the per-character list price, the margin and the 20,000-character cap. A small Node script prints them.

Call GET https://api.sume.com/v1/tts-router/models with your API key and read data.models. Each row has an id, the character cap under capabilities.max_characters, and a pricing object with the list price in micro-dollars per character, the margin and the billing formula.
Read prices from this response, not from prose, so your estimate follows whatever the catalog says today.
A script that prints the catalog
Run it with Node 18 or later and SUME_API_KEY set. Auth is x-api-key or an Authorization: Bearer header.
async function main() {
const res = await fetch("https://api.sume.com/v1/tts-router/models", {
headers: { "x-api-key": process.env.SUME_API_KEY ?? "" },
});
if (!res.ok) throw new Error("HTTP " + res.status);
const { data } = await res.json();
for (const m of data.models) {
const p = m.pricing;
const per1k = (p.list_usd_micros_per_character * 1000) / 1e6;
console.log(
m.id.padEnd(14),
"max", m.capabilities.max_characters,
"list $" + per1k.toFixed(3) + "/1K",
"margin", p.billable_margin,
);
}
}
main().catch((e) => { console.error(e.message); process.exit(1); });What the five ids are
The router is Cartesia Sonic only in v1. The repo docs describe the ids this way.
| Id | Meaning |
|---|---|
| sonic-3.6 | The current stable Sonic that TTS 1.0 uses |
| sonic-3.5 | Explicit earlier version |
| sonic-3 | Explicit earlier version |
| sonic-latest | Alias that resolves to sonic-3.6 |
| sonic-preview | Beta channel; output and availability can change, and it rejects pro voice clones with voice_model_mismatch |
Doing the price arithmetic
The list price is 38 micro-dollars per character, so 1,000 characters list at $0.038. The billed rate multiplies that by the 1.25 margin to give $0.0475 per 1,000, and each job is rounded up to the cent. The script above prints the list price and the margin as the API returns them, so if either changes you see it.
One caution: the prose description of the pricing field in the OpenAPI document still mentions an older 1.10 figure. The Sume docs say 1.25 is what a job is actually charged, so trust the billable_margin value in the response.
Using an id in a generate call
POST /v1/tts-router/generate requires model plus one voice selector and one of transcript or transcript_source. Pin sonic-3.6 when you want stable output across months. Use sonic-latest when you would rather follow the newest stable. Avoid sonic-preview for anything customers hear.
Sources
Related posts
More in Developers
- Reconcile Sume jobs after a deploy or outage: poll what is open
After downtime, read status for every job your own table still shows as open, honor terminal and result_ready, and never resubmit. Python with sqlite.
- Redact faces and license plates: Pillow first, AI edit only to replace
For redaction use Pillow boxes you control; use an AI mask edit on openai/gpt-image-2.5 only to replace a plate or face, from $0.0094 per image on Sume.
- Redeliver a missed video webhook after a bad deploy: one Sume call
Receiver down when the video finished? POST /v1/jobs/{job_id}/webhook/redeliver re-sends job.completed with a fresh signature. Scope, statuses, pitfalls.
- Restyle avatar clip captions with source_caption_id, no re-transcribe
To try a second caption look on an avatar video, send source_caption_id instead of the video URL. Sume reuses the word timings. Cost, errors and a worked flow.
Written by Sume