UtteraUttera

Moving from OpenAI to Uttera is two lines

September 15, 2026

If your code already talks to the OpenAI API to transcribe or to generate speech, you don't have to rewrite it. We speak the same dialect: same routes, same parameter names, same voice names.

from openai import OpenAI

client = OpenAI(
    base_url="https://api.uttera.ai/v1",   # ← 1
    api_key="sk-echo-...",                 # ← 2
)

That's it. The rest of your code stays untouched.

This isn't a brochure claim: the published examples are run against the live API before they're published, with the official openai package and no patching. They're in uttera-examples/openai-sdk, in Python, Node and curl.

What works without touching anything

Works the same Ours only
POST /v1/audio/transcriptions POST /v1/summarize
POST /v1/audio/speech POST /v1/translate
GET /v1/models Voice analysis with ?extras=
Voices alloy echo fable nova onyx shimmer GET /v1/usage/last

The extra endpoints don't get in the way: a client that ignores them behaves exactly as it would against OpenAI. You can migrate today and discover them next month.

The thing you have to change besides the URL

The timeout. And it is by far the most common mistake when integrating.

We hold the connection open for up to 7200 seconds so a long recording can finish. But the default in many libraries is 30 seconds or a minute, and with that you cut off jobs that were doing fine: the server keeps processing, you've already got an exception, and the wrong conclusion is "this doesn't work".

client = OpenAI(base_url="https://api.uttera.ai/v1",
                api_key="sk-echo-...",
                timeout=7200)

For reference: a 100-minute recording is transcribed in 10 to 35 seconds. The long wait isn't for the normal case — it's so the rare case isn't lost.

Three differences worth knowing

Billing is per second of audio, not per request. Ten six-second requests cost the same as one sixty-second request. That changes how it pays to split the work: there's no penalty for making many small calls.

Every response tells you what it cost. The X-Audio-Duration header carries the billed seconds, and the credit headers carry what you have left. You don't have to wait for the end of the month or check somewhere else.

Errors arrive in two shapes. The ones the edge generates carry error and message. The ones the engine generates — a file that can't be decoded, one over the size limit — carry detail. When reading an error, look at error and fall back to detail if it isn't there. It's one line of code and it saves you a useless log the day something fails.

And one thing that doesn't change but you should know

Your audio is processed in Spain and isn't stored. That's not an API difference — your code won't notice — but it probably is a difference for whoever has to sign the contract. It's explained, article by article, in the privacy documentation.

Anything to add or correct? Write to support@uttera.ai. If you correct us, we edit the post and credit you.

← All posts