braidio.cost#
Cost model for braidio’s paid operations (ElevenLabs TTS).
braidio’s only spend is ElevenLabs synthesis — braidio.narrate() /
braidio.text_to_dialogue() and the renderers built on them — billed by
ElevenLabs per character of submitted text. Everything else (ffmpeg
extraction, weaving, loudness normalization) is local and free.
This module turns text into a USD figure so renders can attribute a cost onto
lacing.Artifact.cost_usd and a free estimate_cost() can preview a whole
braidio.Script before any synthesis is paid for.
The figure is an ESTIMATE, priced at a configurable per-1000-character rate
(env RATE_ENV_VAR, the per-model MODEL_USD_PER_1K_CHARS table, or
DEFAULT_USD_PER_1K_CHARS). It equals what ElevenLabs bills for a live
synthesis at that rate — not the provider’s exact invoice. braidio does not yet
see the lower-level mixing on-disk cache, so a render served from that cache
still reports its rate estimate rather than $0 (a safe over-estimate for a
spend ledger; see thorwhalen/braidio#8 to make it exact).
This differs from falaw (which has no default rate and returns None
whenever a real price is unknown): braidio deliberately supplies a default so a
ledger has a number out of the box — while still returning None (unpriced,
never a fake 0.0 for real text) when the rate is explicitly disabled or
invalid. Characters are always counted exactly, so a dollar figure can be
recomputed if the rate changes.
Module Attributes
Env var overriding the USD-per-1000-characters rate (global default for models not in |
|
Default USD per 1000 characters when nothing else is configured. |
|
Confirmed per-model rate overrides (USD per 1000 chars). |
Functions
|
Characters ElevenLabs bills for |
|
Estimate ElevenLabs spend for a |
|
Estimated USD to synthesize |
|
Resolved USD-per-1000-characters rate (most specific source first). |
Classes
|
One billable line of an estimate (a narration beat or a dialogue beat). |
|
A production's estimated TTS spend, exact on characters, honest on dollars. |
- class braidio.cost.CostLine(label, kind, characters, usd, model_id)[source]#
Bases:
objectOne billable line of an estimate (a narration beat or a dialogue beat).
Named to echo
falaw.CostLine(a line within a rollup) rather thanfalaw.CostEstimate(which means a per-call price spec) — so the vocabulary is consistent across the federation.
- class braidio.cost.CostRollup(characters, usd, unpriced, lines=())[source]#
Bases:
objectA production’s estimated TTS spend, exact on characters, honest on dollars.
usdis the sum of the priced lines;unpricedisTruewhen some billable text had no configured rate (sousdis a lower bound). No billable lines (e.g. an all-segment script) givescharacters=0, usd=0.0, unpriced=False. NamedCostRollupto matchfalaw.CostRollup.
- braidio.cost.DEFAULT_USD_PER_1K_CHARS: float = 0.3#
Default USD per 1000 characters when nothing else is configured. Approximate: ElevenLabs bills per credit and the $/credit depends on your plan, so set
RATE_ENV_VARto your plan’s real rate. Kept slightly conservative so a budget over- rather than under-estimates spend.
- braidio.cost.MODEL_USD_PER_1K_CHARS: dict[str, float] = {}#
Confirmed per-model rate overrides (USD per 1000 chars). A model listed here is priced at its own rate — winning over the env override and the default — because a confirmed price is more accurate than a global guess. Empty until ElevenLabs per-model rates are confirmed (e.g.
eleven_v3dialogue vseleven_multilingual_v2).
- braidio.cost.RATE_ENV_VAR = 'BRAIDIO_TTS_USD_PER_1K_CHARS'#
Env var overriding the USD-per-1000-characters rate (global default for models not in
MODEL_USD_PER_1K_CHARS). Set it to your ElevenLabs plan’s real rate for exact ledgers; set it tononeto mark spend as unpriced.
- braidio.cost.billable_chars(text)[source]#
Characters ElevenLabs bills for
text(the whole submitted string).ElevenLabs charges for everything sent — including
eleven_v3audio tags like[excited]— so this is justlen(text). A named function keeps the billing definition in one place if it ever needs to change.- Return type:
>>> billable_chars("hello") 5 >>> billable_chars(None) 0
- braidio.cost.estimate_cost(source, *, model_id=None)[source]#
Estimate ElevenLabs spend for a
braidio.Scriptor a raw string.Free/local work (segment extraction, weaving) contributes nothing. The returned
CostRollupreports exact characters and an honest dollar sum (a lower bound when some text is unpriced; seeusd_per_1k_chars()).- Return type:
>>> from braidio import Script, Narration, SegmentBeat >>> s = Script(title="x", id_slug="01", beats=[ ... Narration(text="a" * 500), SegmentBeat(reference="clip:1")]) >>> estimate_cost(s).characters # only the narration counts; the clip is free 500
- braidio.cost.tts_cost_usd(text, *, model_id=None)[source]#
Estimated USD to synthesize
text;0.0for empty,Noneif unpriced.Empty text is genuinely free (
0.0) regardless of the rate; non-empty text isNoneonly whenusd_per_1k_chars()is unpriced.>>> tts_cost_usd("") 0.0
- braidio.cost.usd_per_1k_chars(model_id=None)[source]#
Resolved USD-per-1000-characters rate (most specific source first).
Resolution: a confirmed per-model rate in
MODEL_USD_PER_1K_CHARS→ the env overrideRATE_ENV_VAR→DEFAULT_USD_PER_1K_CHARS. ReturnsNone(unpriced, not free) when the env override is explicitly disabled (one of_UNPRICED_SENTINELS) or is not a finite, non-negative number — a bad rate must never silently become a dishonest negative/NaN spend.