Sonex Labs

Per-second speech-to-text billing: why an open, silent stream still costs money

Streaming speech-to-text services charge for time, not for words, and most of them bill every second a stream is open whether anyone is speaking or not. So a 5-minute phone call is billed for 300 seconds even if the caller talks for only 90 of them, and a stream left open after the caller hangs up keeps costing money. Vendors differ on which time they count: some bill the open session, others only the audio you send. The savings come from closing streams nobody is using, at hang-up, during holds and transfers and in idle sessions, without clipping the caller's next word.

Per-second STT billing: Per-second speech-to-text billing: why an open, silent stream still costs money
Written by
Anmol Agarwal
Published
Last updated
Reading time
7 min read
On this page
  1. Why streaming speech recognition is billed by time
  2. Two ways vendors meter a streaming session
  3. Where the silent seconds come from on a phone call
  4. How to close streams on hang-up, hold and silence
  5. When keeping the stream open is the right call
  6. Sources

Why streaming speech recognition is billed by time

A streaming transcriber is billed like a taxi meter, not like a word count: the meter runs from the moment the stream opens until it closes. That is fair, because the service holds a connection and a slot on its servers for the whole time, listening for speech it cannot predict. It also means the cost of a call depends on how long the stream stays open, which is often longer than the call and always longer than the talking.

Per-second billing means the meter counts in one-second steps, so a 61-second stream is billed as 61 seconds rather than rounded up to two minutes. The price is usually quoted per minute or per hour. Sonex Labs' Valmiki speech-to-text model is a plain example: $0.00525 per minute of audio, billed by the second, which is $0.0000875 a second. A stream is billed for as long as it is open, on a phone call, in the dashboard playground and through the API alike.

The table shows one 5-minute call four ways at that rate, assuming the caller speaks for 90 seconds in total. Only the last row bills for speech alone, and no streaming service known to us works that way; it is there to show how much of the bill is silence. Rupee figures use ₹95.04 to the dollar (open.er-api.com, 24 October 2026).

Valmiki STT for one 5-minute call, at $0.0000875 a second (our arithmetic)
What the stream doesSeconds billedCost
Open for the whole call300$0.02625 (₹2.49)
Teardown stalls, open 30 s after hang-up330$0.028875 (₹2.74)
Closed during a 2-minute hold180$0.01575 (₹1.50)
Hypothetical: billed on the 90 s of speech only90$0.007875 (₹0.75)

Two ways vendors meter a streaming session

Vendors agree on charging for time but differ on which time, and the difference decides which savings work. Some count the session: every second the connection is open. Others count the audio: every second of sound you actually send. A third question is rounding, since a vendor that rounds each session up to a minimum charges short sessions more than their length.

Rounding matters most for short calls. Deepgram, which places itself among per-second vendors, writes that some competitors round each stream up to 15-second blocks or a full minute, and gives the example of an 11-second IVR call billed as 15 seconds (Deepgram's pricing breakdown). That is one competitor describing others, so read each vendor's own billing terms rather than a summary.

Session-metered: the open connection is the meter

AssemblyAI is the clearest example. Its pricing page says streaming is billed on "the time the WebSocket connection is open", so a session open for 60 minutes with 30 minutes of audio is billed for 60 (AssemblyAI pricing). At $0.15 an hour for Universal-Streaming, a 5-minute session costs $0.0125.

Its documentation adds two traps. Each session is billed separately, so a 5-minute call streamed twice under two session IDs is billed as 10 minutes, and a session that is never terminated closes itself after 3 hours and is billed for all 3 (AssemblyAI FAQ). Sending the termination message is what stops the meter.

Audio-metered: only the sound you send counts

Smallest AI's Pulse STT is billed the other way. Its documentation says a connection "held open with keep-alives and no audio accrues no charge" (Smallest AI docs). On an audio-metered service you can stop sending audio during long silences, keep the socket alive with small keep-alive messages, and avoid the delay of reconnecting.

Deepgram gives developers the same tool. Its KeepAlive message, {"type": "KeepAlive"}, holds a connection open without audio; Deepgram closes a connection with a NET-0001 error after 10 seconds with neither, and recommends a keep-alive every 3 to 5 seconds (Deepgram docs). The page describes the feature as a way of optimising costs without saying how silence is billed, so treating Deepgram as audio-metered is our reading; confirm it for your contract. Its streaming Nova-3 is $0.0048 a minute pay-as-you-go, shown as a limited-time promotional rate.

  • Where the session is the meter, pausing the audio saves nothing; only closing the stream helps.
  • Where the audio is the meter, stop sending during long silences and send keep-alives, which keeps reconnects off the critical path.
  • Either way, find out whether each session is rounded up to a minimum before optimising.

Where the silent seconds come from on a phone call

Most silence on a call cannot be avoided, and some of it you pay for on purpose. Pauses between turns are short and need the stream open. While the agent speaks, the stream must keep listening if you want the caller to be able to interrupt, which is what makes barge-in work; how voice bots handle interruptions and backchannels explains why that matters. Holds, transfers, voicemail greetings and IVR menus are longer and usually need no transcription at all.

The expensive silence is the kind nobody sees: streams left open after the call has ended. In Sonex's call engine, the pipeline normally shuts every service down on hang-up. When one processor stalled that shutdown, the speech-to-text connection was never told to close, and its socket ran on in the background for tens of seconds. Under back-to-back calls, enough of these zombie sessions piled up to exceed an upstream limit on concurrent sessions, and the next calls' transcription failed with HTTP 429 (too many requests) errors. The engine now closes the STT connection directly on hang-up, with a 2-second limit, instead of relying on the shutdown to reach it.

Clients cause the same leak from the other end. On Sonex's public streaming API, a test client once sent a 4.5-second clip and then held the connection until the idle timer closed it, and was billed for 36 seconds. The API now ends a session as soon as the client sends {"type": "end"}, after giving the last words up to 5 seconds to finalise. It also closes any session with no recognised speech for 30 seconds, and caps a single connection at 10 minutes. The sample below ends its session explicitly; a fuller speech-to-text API tutorial in Python covers files and options.

import asyncio
import json
import wave

import websockets  # version 13 or later


async def transcribe(path: str) -> None:
    async with websockets.connect(
        "wss://api.sonexlabs.com/v1/transcribe/stream",
        additional_headers={"Authorization": "Bearer YOUR_API_KEY"},
    ) as ws:
        while json.loads(await ws.recv())["type"] != "ready":
            pass
        with wave.open(path, "rb") as w:  # 16 kHz mono 16-bit PCM
            frames = w.getframerate() // 10  # 100 ms per message
            while chunk := w.readframes(frames):
                await ws.send(chunk)
                await asyncio.sleep(0.1)  # real time, like a live caller
        await ws.send(json.dumps({"type": "end"}))  # stop the meter now
        async for message in ws:
            event = json.loads(message)
            if event["type"] == "final":
                print(event["text"])
            elif event["type"] == "done":
                print("seconds billed:", event["seconds_billed"])


asyncio.run(transcribe("call_16k.wav"))
Streaming a recording to the Valmiki API and ending the session explicitly. The done message reports the seconds billed, so you can check the meter yourself.

How to close streams on hang-up, hold and silence

Close on clear events, not on guesses. Hang-up is the clearest: close the STT connection yourself, directly and with a timeout, the moment the carrier reports the call has ended, and log the open and close times with the call ID. Then compare your provider's count of sessions with your count of calls. More sessions than calls, or provider minutes well above call minutes, means something is leaking.

Holds and transfers are the next easiest, because your own system starts them. Close the stream when hold music starts or the call leaves for a human, and open a new one when the caller returns to the agent. Open it a moment before you need it, buffer the caller's audio while the connection is set up, and send the buffer first. A new stream needs a network handshake and a session setup, and audio that arrives in that gap is otherwise lost.

Long silence in the middle of a conversation is the hardest case. A local voice activity detector (VAD), software that decides whether a stretch of audio contains speech, can tell you no one has spoken for, say, 15 seconds, the idle limit Sonex uses in its dashboard playground. With an audio-metered vendor, stop sending and switch to keep-alives. With a session-metered vendor, closing is the only saving, so keep the limit long enough that a caller who is thinking is not cut off, and reopen on the first sign of speech. A VAD can also clip the start of speech, so test it on real calls; silence handling on Twilio media streams shows what phone-line silence looks like in practice.

Decision chart for when to close a streaming STT connection to avoid per-second billing for silence on calls
A yes/no test for whether a streaming speech-to-text connection should be open at a given moment of a phone call.

When keeping the stream open is the right call

Closing streams has costs of its own, and at small volumes they can outweigh the savings. Each reconnect risks clipping the first syllable of the caller's next sentence, and some services carry context across a session that a new stream loses. Every extra open and close is also one more thing that can fail in the middle of a call, and a missed word costs more in a booking or a payment call than a few seconds of transcription.

So do the arithmetic for your own volume before writing the code. Closing during a 2-minute hold saves 120 seconds, $0.0105 per call at Valmiki's rate. Across 100,000 such calls a month that is $1,050, worth an afternoon of engineering; across 1,000 it is $10.50, and probably not. The zombie-session fix is different: it costs almost nothing to build, saves 30 seconds per affected call in the table above, and prevents an outage, so do it whatever your volume.

Keep the line in proportion, too. In a quality API stack priced in October 2026, speech-to-text was about a fifth of the cost per call-minute, behind text to speech, as the self-hosting cost model breaks down. The same time-based meter also applies to a self-hosted GPU, which bills every hour it runs, a point the self-hosted Whisper comparison takes further. Fix the leaks first, then the holds, and leave the pauses inside a live conversation alone.

Sources

  1. AssemblyAI pricing: streaming billed on session duration (checked 24 Oct 2026)Official
  2. AssemblyAI docs: how Universal-Streaming session-based pricing worksOfficial
  3. Smallest AI docs: Pulse STT keep-alive and billing on audio durationOfficial
  4. Deepgram docs: Audio keep alive (checked 24 Oct 2026)Official
  5. Deepgram pricing (Nova-3 streaming promotional rate, checked 24 Oct 2026)Official
  6. Deepgram: speech-to-text API pricing breakdown, 2025 edition (a competitor's view of rounding)Secondary
  7. ExchangeRate-API open access rates (USD to INR, 24 October 2026)Official

Change log: 24 Oct 2026, First published. Later the same day, rewritten as one continuous article that opens on how streaming STT is metered rather than on a Sonex price: added AssemblyAI's per-session and three-hour auto-close rules, Smallest AI as a documented audio-metered example, and Deepgram's promotional pricing; the takeaways and FAQs were folded into the body

Questions about your calling setup?

Tell us what you call about, where and in which languages.