List Sume TTS Router models and prices in Python: one GET

GET /v1/tts-router/models returns five Sonic ids with per-character price and constraints. A short Python script prints each model's price per 1,000 characters.

5 min readSume
All posts

Send GET /v1/tts-router/models with your Sume API key and you get the router catalog: five Cartesia Sonic ids, each with a 20,000-character limit and a per-character price. The script below prints the price per 1,000 characters for each model, plus any constraints. It works out to $0.0475 per 1,000 characters on all five.

What the catalog returns

The response is {data: {models: [...]}}. Each model has an id, a name, capabilities.max_characters, a pricing object and a constraints array. The pricing object holds the provider list price in micro-dollars per character, plus billable_margin, the multiplier that Sume applies before rounding the job up to a whole cent.

The catalog publishes the margin that a reservation really uses, so you can compute a quote without guessing. The list price is 38 micro-dollars per character, which is $0.000038. Times 1.25 gives $0.0000475 per character, or $0.0475 per 1,000.

TTS Router models in the Sume catalog (read 2026-10-07)
Model idNotes
sonic-3.6current stable Sonic
sonic-3.5earlier Sonic
sonic-3earlier Sonic
sonic-latestalias for sonic-3.6, never sonic-preview
sonic-previewprovider beta; rejects pro voice clones with voice_model_mismatch

The script

It needs only the standard library and an API key in SUME_API_KEY. The User-Agent header is set so your calls are identifiable in logs.

import json
import os
import urllib.request

req = urllib.request.Request(
    "https://api.sume.com/v1/tts-router/models",
    headers={
        "Authorization": "Bearer " + os.environ["SUME_API_KEY"],
        "User-Agent": "tts-catalog-check/1.0",
    },
)
with urllib.request.urlopen(req, timeout=30) as resp:
    models = json.load(resp)["data"]["models"]

for m in models:
    p = m["pricing"]
    per_1k = p["list_usd_micros_per_character"] * 1000 * float(p["billable_margin"]) / 1e6
    print(m["id"], m["capabilities"]["max_characters"], f"${per_1k:.4f} per 1,000 chars")
    for note in m["constraints"]:
        print("   -", note)

Reading the output

Expect five lines, each with 20000 and $0.0475, and two with constraint notes (sonic-latest and sonic-preview). If a number differs from this, trust the response, because the catalog is the source of truth and this article is a dated snapshot.

Use the constraints array as a gate in code. A job that pins sonic-preview with a pro voice clone fails with voice_model_mismatch before it produces audio. Checking the constraint text on your side is cheaper than learning it from a failed job.

When to call it

Call the catalog once at deploy time and cache it for the process lifetime. The ids change rarely. A weekly check that fails loudly if a model you pin has disappeared is enough.

For a cost quote in a form, you need only the price per character and the one-cent minimum: cost = max(1 cent, ceil(characters x 0.00475 cents)). A 1,000-character script is 4.75 cents and bills 5 cents. A 20,000-character script is $0.95, the most one request can cost.

Checking the quote against a real job

After a job completes, compare the quoted cost with the amount charged. They should agree because the catalog publishes the margin the reservation uses. If the two ever differ, log the model id, the character count and the two amounts, and raise it with support rather than adjusting your code to match.

Keep that log line cheap and structured. Four fields are enough: model id, characters, quoted cents and charged cents. A week of these lines shows whether rounding behaves as the one-cent-minimum rule predicts, and it makes any later price change visible the day it happens.

Remember the limits that the catalog does not list. One request carries at most 20,000 characters and 1,200 seconds of audio, whichever is reached first. Long scripts need splitting on paragraph boundaries, then joining with timeline audio.

Related posts

More in Developers

All Developers posts

Written by Sume