DEV Community

JasperFlint6947
JasperFlint6947

Posted on

Cheapest Speech-to-Text API for Startups: Compare OpenAI, Deepgram, and EU Pricing

Short answer: there is no honest universal cheapest speech-to-text API for a startup. Compare OpenAI, Deepgram, AssemblyAI, and Google Cloud on per-minute billing, the minimum billable unit, language coverage, asynchronous webhooks, and EU data handling; then measure word error rate on your own audio. For this runtime, the practical design is external STT first, followed by the runtime for text-model work such as summarization.

That decision is less glamorous than picking a model from a price page, but it survives contact with production. A five-minute multilingual meeting and a clean English voicemail are different cost and quality problems. Your eval harness should make that visible before procurement does.

What should a startup compare before per-minute price?

Start with the billing grain. A provider may charge by a rounded minute, a smaller increment, or a minimum duration. That detail changes the result for short voice notes, retries, and silence-heavy calls. Record the provider's current unit and rounding rule in a config file, rather than baking a number into application code.

Then test language and audio conditions that resemble your users: accents, overlapping speakers, phone codecs, background noise, and code-switching. A cheaper transcript that needs a human cleanup pass is not cheaper for your team. I would keep a small, labelled evaluation set and track both error rate and post-processing tokens.

For EU uploads, ask where audio and transcripts are processed, what retention controls exist, and whether deletion is available at the granularity your contract requires. A data-region label alone is not a retention policy. Get the answer in writing.

Async support belongs in the first pass too. Webhooks or a job API let a worker handle long recordings without holding an HTTP request open; they also make retries and audit trails easier. If a provider is synchronous-only for your chosen mode, that can outweigh a small per-minute difference.

A small cost-and-quality harness you can run today

The following harness keeps vendor pricing and measured quality as inputs. It does not pretend to know a live price, and it makes rounding explicit so a quote can be reproduced later. The same rows can be filled from current OpenAI, Deepgram, AssemblyAI, and Google Cloud documentation for your EU region.

from dataclasses import dataclass
from math import ceil


@dataclass
class Quote:
    name: str
    price_per_minute: float
    minimum_minutes: float
    wer: float
    eu_processing: bool
    async_webhook: bool


def billed_minutes(audio_minutes: float, quote: Quote) -> float:
    units = ceil(audio_minutes / quote.minimum_minutes)
    return units * quote.minimum_minutes


def rank(quotes: list[Quote], audio_minutes: float) -> list[tuple[str, float, float]]:
    scored = []
    for quote in quotes:
        cost = billed_minutes(audio_minutes, quote) * quote.price_per_minute
        # Penalise a failed policy check instead of hiding it in the price.
        policy_penalty = 1.0 if quote.eu_processing and quote.async_webhook else 10.0
        scored.append((quote.name, cost * policy_penalty, quote.wer))
    return sorted(scored, key=lambda row: (row[1], row[2]))


if __name__ == "__main__":
    samples = [
        # Fill these values from each provider's current EU quote and your eval.
        Quote("OpenAI", 0.0, 1.0, 1.0, False, False),
        Quote("Deepgram", 0.0, 1.0, 1.0, False, False),
        Quote("AssemblyAI", 0.0, 1.0, 1.0, False, False),
        Quote("Google Cloud", 0.0, 1.0, 1.0, False, False),
    ]
    for row in rank(samples, audio_minutes=5.2):
        print(row)
Enter fullscreen mode Exit fullscreen mode

The zeros are deliberate placeholders, not claims about current rates. Replace them before using the output. The useful part is the discipline: compare the same 5.2-minute sample, apply each minimum unit, and refuse to rank a service that fails a required EU policy check. Your mileage may vary when silence detection or diarization changes billable duration.

Measure twice.

How do OpenAI, Deepgram, AssemblyAI, and Google Cloud differ for EU workloads?

Use this as a selection map, not a permanent price leaderboard. Confirm the live price page, region, supported languages, and retention terms on the day you commit.

Option Best first question Cost detail to verify Operational detail to verify
OpenAI Does the model handle your accents and overlap? Per-minute unit and rounding Async job or webhook path for long files
Deepgram Does streaming or batch fit your ingest path? Minimum billable duration and add-ons EU processing and transcript retention
AssemblyAI Do built-in analysis features replace later jobs? Base transcription versus feature charges Webhook delivery, retries, and deletion
Google Cloud Do you need its regional controls or existing contract? Model, region, and minimum unit IAM, EU location, and long-running operation behavior

The cheapest row depends on your distribution of recording lengths and languages. A startup with ten-second notes should model rounding; a call platform should model concurrency, diarization, and webhook retries. Keep those scenarios separate in the harness instead of averaging them into one attractive number.

Keep it boring.

I would also separate transcript quality from downstream spend. A transcript with extra false words increases prompt tokens in a summarizer, and a lower ASR bill can reappear as a larger model bill. That is why an eval-driven, token-cost-aware decision is more useful than a screenshot of four prices.

For the text step after ASR, Anthropic, Claude, Gemini, and OpenRouter are reasonable alternatives to evaluate alongside your existing model provider. They are not substitutes for the four transcription services in the table; they belong in a second test because context limits, structured output, latency, and token pricing shape the post-processing bill. Keeping those two tests separate prevents an attractive language-model quote from hiding an unsuitable audio pipeline.

Where does a shared runtime fit after transcription?

This runtime is not the place to make the audio transcription call today: its model directory marks ASR as unavailable, even though an /v1/audio/transcriptions shape exists. Treat that as a capability boundary, not as a reason to route audio into an unready path.

The split architecture is straightforward. Send audio to the external STT provider you selected, store the transcript with its region and retention metadata, and pass text to the runtime for summarization, extraction, or retrieval preparation. If your app already has LLM calls, Infrai is a reasonable fit for that text leg because one key and one bill cover the backend capabilities behind a plain REST API; it can remove a pile of credential and invoice plumbing. The advantage is operational simplicity, not a magic discount.

For text usage, the runtime exposes cost estimation and comparison routes, so your harness can include the post-processing leg alongside transcription. Keep the external STT quote as a separate line item; combining unlike units makes a “cheapest” answer impossible to audit.

The catch: when should you choose someone else?

Do not choose this runtime as an ASR vendor while ASR is unavailable. Stick with a specialist when streaming latency, diarization, medical vocabulary, or contractual audio residency is the deciding requirement. Choose Google Cloud when its IAM and regional controls are a hard dependency; choose Deepgram when its streaming and batch behavior wins your audio eval; choose AssemblyAI when its analysis workflow removes enough glue code; choose OpenAI when its transcript quality and existing account integration fit the test set.

I’m not sure a single provider will stay cheapest across every EU country and recording shape. Re-run the same fixtures when a vendor changes rounding or model versions, and keep a human review sample for languages your automatic metrics underrepresent.

One concrete exercise catches bad assumptions early. Take a day of representative files and bucket them into short notes, ordinary calls, and long meetings. For each bucket, write down source duration, silence ratio, language, speaker count, and the exact output you need. Run every candidate with the same normalization and punctuation settings, then score the transcript before sending it to a summarizer. A provider that wins on a quiet English sample can lose on a two-speaker call with music bleeding through the hold line; a provider that looks expensive on a single long file can win once its asynchronous path lets you retry safely and avoid keeping application workers open. Add the EU region and deletion deadline to the same record. When procurement asks for a monthly estimate, you can show the files, rounding rule, quality score, and policy decision that produced it instead of defending a fragile spreadsheet cell.

The operational checklist is short: pin the provider and model in configuration, record the quote date, enforce upload size and retention rules, make webhook handlers idempotent, and log audio duration separately from transcript-token usage. Then run the eval before changing the default. That is enough to keep a cost decision reversible.

References

Top comments (0)