HomeBlog → Speech-to-text pricing: what you actually pay for

Speech-to-text pricing: what you actually pay for

Published 2026-08-05 · 6 min read

Transcription pricing looks simple — a rate per minute — and then the first invoice does not match the estimate. The gap is almost never the rate. It is the minutes you did not realise you were sending: silence, duplicates, retries and files nobody ever reads.

The unit is a minute of audio, not a word

Start here, because it explains most surprises. You are billed for the duration of the audio you upload, not for the amount of text that comes back.

Consequences worth internalising:

Almost every optimisation below is a variation on one idea: send less audio, not less speech.

Where the unexpected minutes come from

SourceTypical wasteFix
Leading and trailing silence in call recordings10–30%Trim with ffmpeg before sending
Hold music and IVR menus5–20%Cut the segment before the answer
The same file sent twice after a crashup to 100%Idempotent pipeline, skip finished files
Test runs left in production codevariesSeparate key, watch the client area
Recordings nobody ever opensoften the majorityTranscribe on demand, not everything

The last row is usually the biggest one and the least technical. Teams often transcribe an entire archive because it is easy, then use two per cent of it.

Estimating your own spend

Do not extrapolate from a price page — measure your own audio. The whole calculation is two numbers:

ffprobe -v error -show_entries format=duration -of csv=p=0 sample.mp3
import pathlib, subprocess

def minutes(p):
    out = subprocess.run(["ffprobe", "-v", "error", "-show_entries",
                          "format=duration", "-of", "csv=p=0", str(p)],
                         capture_output=True, text=True).stdout
    return float(out) / 60

month = sum(minutes(p) for p in pathlib.Path("recordings").glob("*.mp3"))
print(f"{month:.0f} min per month")

Multiply by your rate and you have the monthly figure. Sanity anchors that hold in practice: a support line with 200 calls a day at four minutes each is roughly 16 000 minutes a month; a weekly podcast is about 4 hours; a team of ten on daily half-hour meetings is around 600 minutes.

Package plus overage, and why it exists

Most plans combine a monthly fee that includes a package of minutes with a per-minute rate above it. The arithmetic is worth doing once:

bill = monthly_fee + max(0, used_minutes - included_minutes) * rate

Two failure modes to avoid. Buying a package far above your volume means paying for minutes you never use — the included minutes do not roll over. Staying on pure pay-per-minute at high volume means missing the discount the package represents. Look at three months of actual usage before committing to either.

A hard limit on the package is a safety feature, not a restriction: it stops a runaway loop from generating an invoice nobody approved. Turn it on while you are still developing.

API or your own GPU

The honest comparison is not “rate per minute versus zero”. Self-hosting moves cost from a line item to a set of things that are easy to forget:

CostAPIOwn GPU
Per minute of audiorate0
Hardware0card + machine, amortised
Electricity and hosting0continuous, whether idle or not
Setup and maintenance0engineer time, ongoing
Idle timefreefull price

The break-even is about utilisation, not volume. A GPU that runs a few hours a day loses to an API, because you pay for the twenty idle hours too. A GPU saturated around the clock wins. In between, the deciding factor is usually whether you want to be responsible for a machine at 3 a.m.

There is a third reason that has nothing to do with money: some data is not allowed to leave your perimeter. That is a requirement, not an optimisation, and it settles the question on its own.

Cutting the bill without losing quality

  1. Trim silence. The cheapest single change on call recordings — often 10–30% off, with zero quality impact.
  2. Do not transcribe what nobody reads. Transcribe on request, or only calls above a duration threshold, and watch what people actually open.
  3. Make the pipeline idempotent. Repeating finished work after a crash is pure waste; skipping finished files removes it.
  4. Use a separate key for development. Test traffic mixed into production numbers hides both problems.
  5. Check usage weekly, not monthly. A loop that sends the same file in a cycle is obvious on day one and expensive by day thirty.
# trim the silence at both ends
ffmpeg -i call.mp3 -af silenceremove=start_periods=1:start_threshold=-45dB:stop_periods=-1:stop_threshold=-45dB:stop_duration=2 short.mp3

Try it on your own recordings. Sign-up takes a minute, and the free minutes are enough to judge the quality.

Get a free API key

Frequently asked questions

Am I billed per minute of audio or per word of text?

Per minute of audio you upload. The length of the resulting text changes nothing, which is why silence and hold music cost exactly as much as speech.

Do I pay for a recording that turned out to be silent?

Yes — the audio was still processed, even though the response is empty. Trimming silence before sending is the direct fix.

Are failed requests charged?

A request that returns an error is not billed for audio minutes. What does cost money is repeating a successful transcription, which is why a resumable pipeline matters.

Is running Whisper on my own GPU cheaper?

Only at high utilisation. A card that idles most of the day loses to per-minute billing once you count hardware, power and maintenance. Round-the-clock load is where self-hosting wins.

How do I avoid an unexpected invoice?

Estimate the volume with ffprobe before the first batch, keep the hard package limit on during development, and check the usage numbers in the client area weekly rather than at the end of the month.

Related reading