Connectors
Uttera doesn't live alone: it lives inside what you already have. This section collects the ways of plugging it in — the ones that already work, the ones we bring ready-made, and the ones we're looking at — plus the open source it is built on.
| Folder | What's in it |
|---|---|
| openai-sdk | Uttera through the official OpenAI SDK, in Python, Node and curl |
| asterisk/recordings | Transcribing the calls your phone system already records, without touching the dialplan |
| asterisk/agi | Speaking inside the call and hearing the caller |
| n8n | Our own node, plus workflows that import without installing anything |
| openclaw | A skill for agents: transcribe, summarize, translate and speak |
We speak OpenAI's dialect
The two main services follow exactly the same shape as the OpenAI API: same routes, same parameter names, same voice names and same responses.
| Endpoint | Compatible |
|---|---|
POST /v1/audio/transcriptions | Yes. file, model=whisper-1, language, prompt, response_format, temperature |
POST /v1/audio/speech | Yes. model=tts-1 / tts-1-hd, input, voice, response_format, speed |
GET /v1/models | Yes. Returns tts-1, tts-1-hd and whisper-1. It's what the SDK calls as soon as the client is constructed |
Voices alloy · echo · fable · nova · onyx · shimmer | Yes, under those same names |
/v1/translate · /v1/summarize · ?extras= · /v1/usage/last | Ours. They don't exist in OpenAI, and they don't get in the way of anyone who doesn't use them |
In practice this means that anything written for the OpenAI API works by changing two lines: the base address and the key. Including their official SDK:
from openai import OpenAI
c = OpenAI(api_key="sk-echo-...", # your Uttera key
base_url="https://api.uttera.ai/v1") # and our address
audio = c.audio.speech.create(model="tts-1", voice="nova",
input="Your order ships tomorrow.")
open("voice.mp3", "wb").write(audio.content)
with open("recording.mp3", "rb") as f:
print(c.audio.transcriptions.create(model="whisper-1", file=f,
response_format="text"))
openai package without patching anything: it generates the audio,
transcribes it back and returns the original text.Which is where the interesting part comes from: everything that already knows how to talk to OpenAI knows how to talk to us — local agents, self-hosted chat interfaces, plugins, scripts somebody wrote a year ago — with the difference that the audio never leaves the European Union. For many companies that is the only reason the project moves from demo to production.
Asterisk and phone systems
It's the most requested integration, because it's where the voice actually is. We bring two ready-to-use AGI scripts: one says a text inside the call and the other listens to the caller and leaves what they said in a dialplan variable.
exten => 101,1,Answer()
same => n,AGI(uttera-decir.agi,"How can I help you?")
same => n,AGI(uttera-oir.agi,8,en)
same => n,NoOp(The caller said: ${UTTERA_TEXTO})
From there it's your call: a menu, a database lookup, a language model. And for the most
common case — transcribing calls that are already recorded — the example brings the
skeleton with MixMonitor and a hangup hook.
What the example solves and what costs a day to discover on your own:
| Trap | What happens if you don't know |
|---|---|
| Uttera generates at 24 kHz, the telephone channel runs at 8 kHz | Asterisk plays the file at its own rate: the voice comes out fast and high-pitched |
| Missing silence at the end of the file | Asterisk cuts off the last syllable |
| Whisper doesn't stay quiet at silence | It returns an invented sentence — "Thanks for watching" — because that abounds in its training data. You pay for it, and worse, you act on it |
The quoting in SET VARIABLE | Text with spaces arrives split and the variable keeps only the first word |
| API timeouts during a call | Two hours of waiting with a person on the phone. In telephony you cut at 30 s and say something |
The complete code and dialplan are in the examples repository, with an explanation of each one.
The calls you're already recording
Before you consider speaking inside the call, look at this: your phone system is already writing audio files into some folder. There are two scripts that read them and leave the transcript and the analysis beside them, and you don't have to touch the dialplan. One cron line and you have last week's calls transcribed.
It's the code we run in production ourselves, with the parts specific to our installation taken out. It carries three things inside that cost us dearly: telling a recording in progress from an old one, asking for transcription and analysis in a single upload instead of four, and a date filter by default — a batch process with no window walks the entire history on every pass, and the day it meets a real archive it queues years of calls at once.
n8n and automation
If you use n8n, there are two ways and the second needs nothing installed.
Workflows ready to import. You download them, import them, and they work with the stock HTTP node — including on n8n cloud. The most useful is the one that watches a folder of recordings every fifteen minutes and sends each one to be summarized: it is exactly the case of someone who already has a phone system recording and only needs somebody to read those recordings. No dialplan to touch.
Our own node. n8n-nodes-uttera adds transcribe, summarize, translate
and text-to-speech as operations of a single node, with the credential stored in n8n instead
of loose in every request.
Agents and assistants
Because of the compatibility above, any agent or interface that speaks OpenAI's dialect uses Uttera without an adapter: point it at our address. That covers local installs of assistants and self-hosted chat panels, which is exactly the scenario our engines were born for: keeping the audio inside the private domain.
If your agent supports tools, the endpoints that aren't OpenAI's — summarize, translate, analyze the voice — describe well as standalone tools: they take a file and return JSON.
For OpenClaw agents there's a ready-made skill: four scripts — transcribe,
summarize, translate and speak — and a SKILL.md that tells the agent when
to use each one and what the traps are. That part is what really matters: that it knows not
to send silence to be transcribed, that line breaks cost money when synthesizing, and that
what comes back from a transcript is untrusted text it must not execute.
The open source underneath
The engines that move Uttera are published under the Apache 2.0 license. It isn't marketing: they are the same ones running in production.
| Repository | What it is |
|---|---|
| uttera-tts-hotcold | Text-to-speech server with cold and hot start. Several engines behind one API |
| uttera-tts-vllm | The same service on vLLM, for real concurrent load |
| uttera-stt-hotcold | Speech-to-text server, same pattern |
| uttera-stt-vllm | Speech to text on vLLM |
| uttera-benchmarks | The corpora, the measurement harness and the raw results behind every number we publish |
Why they're open
For three reasons, and none of them is generosity:
Because you can run it yourself. If your case can't have the audio leaving your network — or you simply prefer your own hardware — clone the repository and stand the service up. What we sell is not having to: the GPUs, the availability, the routing between nodes, and somebody getting out of bed if something breaks.
Because an engine nobody can audit doesn't deserve your audio. We say we keep nothing and that nothing goes to third parties. With the code in front of you, that can be checked instead of believed.
Because numbers without the setup are worthless. Everyone publishes "X requests per second on a Y" without saying with which corpus, at what concurrency, or at which percentile. The measurements repository carries the whole corpora, the protocol and the raw results, precisely so you can repeat the test and contradict us.
Connectors in the works
What's next, in the order people ask for it:
| Connector | What for |
|---|---|
| CRM | So the transcript and summary of a call land in the customer's record on their own |
| Recordings from other phone systems (FreePBX, 3CX, Issabel) | The same thing the Asterisk connector already does, adapted to where each one leaves its files |
| Voice note to text in messaging | The fastest-growing use case: nobody wants to listen to a four-minute voice note |
If the one you need isn't there, tell us: the order is decided by whoever asks.