PhoenixKitAI.TtsPricing (PhoenixKitAI v0.16.0)

Copy Markdown View Source

Estimated per-request cost for a completed TTS request, in nanodollars (1/1,000,000 of a dollar — the same unit Request.cost_cents already uses for chat/embeddings, despite the field's legacy name).

No TTS provider self-reports cost the way OpenRouter's chat completions do (there's no usage object at all in an /audio/speech or xAI /tts response) — so unlike Completion.extract_usage/1, this can't extract a real figure from the response. It has to come from a hand-maintained rate table instead.

Rates as of 2026-07-16 — verify against each provider's current pricing page before trusting for billing-critical use. These will drift; this table needs periodic manual updates, same as any other hardcoded rate table. Sources:

Mistral and xAI bill per character, and input_chars is exact (String.length/1 on the request text), so their cost is exact given the rate is current. OpenAI bills per token on both legs, but /audio/speech returns no token counts to read back — estimating a token count from characters (further split into an input-text leg and an audio-output leg) would compound two guesses, so this uses the commonly-cited blended rate (~$0.015/minute of generated audio) applied to a duration estimated from audio_bytes at the assumed bitrate instead — one estimate, not two. Treat it as approximate wherever it's displayed.

Summary

Functions

Estimated cost in nanodollars for a completed TTS request, or nil if provider isn't in the rate table — same as no cost being available today, not a new failure mode. input_chars and audio_bytes are exactly what PhoenixKitAI.speak/3 already records in the request's metadata.

Functions

cost_nanodollars(provider, input_chars, audio_bytes)

@spec cost_nanodollars(String.t(), non_neg_integer(), non_neg_integer()) ::
  non_neg_integer() | nil

Estimated cost in nanodollars for a completed TTS request, or nil if provider isn't in the rate table — same as no cost being available today, not a new failure mode. input_chars and audio_bytes are exactly what PhoenixKitAI.speak/3 already records in the request's metadata.