UtteraUttera

Connectors

At a glance. OpenAI compatibility and connectors: Asterisk, n8n, Telegram, Slack, MCP and agents. Key: change the base_url to https://api.uttera.ai/v1 and the rest of your code stays the same.

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.

Everything described here is code you can download: github.com/uttera/uttera-examples. Every example is run against the live API before it's published, and where something couldn't be tested end to end, its README says so.
FolderWhat's in it
openai-sdkUttera through the official OpenAI SDK, in Python, Node and curl
asterisk/recordingsTranscribing the calls your phone system already records, without touching the dialplan
asterisk/agiSpeaking inside the call and hearing the caller
n8nVerified community node (transcribe, summarize, translate, speak, effects, music). Ready-to-import workflows under “n8n and automation”
openclawA 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.

EndpointCompatible
POST /v1/audio/transcriptionsYes. file, model=whisper-1, language, prompt, response_format, temperature
POST /v1/audio/speechYes. model=tts-1 / tts-1-hd, input, voice, response_format, speed
GET /v1/modelsYes. 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 Β· shimmerYes, under those same names
/v1/translate Β· /v1/summarize Β· ?extras= Β· /v1/usage/lastOurs. 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"))
This is tested, not assumed. The example above runs with the official 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:

TrapWhat happens if you don't know
Uttera generates at 24 kHz, the telephone channel runs at 8 kHzAsterisk plays the file at its own rate: the voice comes out fast and high-pitched
Missing silence at the end of the fileAsterisk cuts off the last syllable
Whisper doesn't stay quiet at silenceIt 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 VARIABLEText with spaces arrives split and the variable keeps only the first word
API timeouts during a callTwo 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 is an n8n-verified community node: install it from n8n's settings (Community Nodes) or with npm i n8n-nodes-uttera. It adds transcribe, summarize, translate, text-to-speech, sound effects and music as operations of a single node, with the credential stored in n8n instead of loose in every request. Source at github.com/uttera/n8n-nodes-uttera.

Two details the node has already solved: the timeout is two hours β€” n8n's default cuts off long recordings that were doing fine β€” and "continue on error" works per item, which matters when processing a whole folder, where there's always some corrupt recording that shouldn't bring the batch down.

Telegram

Uttera has a Telegram bot, @Uttera_bot, to transcribe and summarise voice notes without leaving the chat. Whatever it does is billed to your account, with the same credits as the API.

Link your account (once). Go to your account β†’ Connect applications β†’ Telegram: the bot opens already linked to your account (under the hood it's a /start with a single-use link; you paste no key). From then on the bot knows who you are and who to bill.

Using it. Send it a voice note (or an audio file) and it returns the transcription. Below it, buttons do more with that same recording:

Commands. /account opens your account (credits, expiry, billing); /lang en|es|fr|de changes the language of the bot's replies; /start links your account again; /help is a reminder of all this.

The bot doesn't keep your audio: it uses it only to produce the result, and the audio Uttera generates carries the inaudible watermark required by the EU AI Act, just like in the API and the apps.

Slack

Uttera has a Slack app to transcribe, summarise and translate voice notes without leaving Slack. Whatever it does is billed to your account, with the same credits as the API.

Install the app in your Slack (once per workspace). A workspace admin opens app.uttera.ai/slack/install and clicks Allow: that adds the Uttera app to that Slack. After that, each user links their own account as explained below.

Link your account (once). In your account β†’ Connect applications β†’ Slack you get a single-use code. In Slack, type /uttera connect <code> and your user is linked to your Uttera account (you paste no key).

Using it. Share a voice note (or an audio file) with the bot and it returns the transcription, with the same buttons as in Telegram:

Commands. /uttera account opens your account; /uttera lang en|es|fr|de changes the reply language; /uttera connect <code> links; /uttera help is a reminder of all this.

Where to talk to it. A Slack app only receives audio from a direct message with it or from a channel it has been invited to (/invite @Uttera). As with everything in Uttera, we don't keep your audio and the audio we generate carries the inaudible watermark required by the EU AI Act.

Skill: local audio in Claude, ChatGPT, Gemini and OpenClaw

A Skill is a folder with instructions and a small script that your assistant loads when needed. The Uttera Skill lets you attach an audio file from your disk right in the chat and ask it to transcribe, summarize, build a signed PDF report with an evidence graph, translate it (to text or to voice), tell who speaks, score pronunciation, clone a voice or read text aloud. The script runs in the assistant's code sandbox: it reads the attached file and uploads it to api.uttera.ai, so the audio never passes through the model (it can't decode audio). It's billed to your account, on the same credits as the API.

Download it. In your account β†’ Connect apps, click your assistant's button (Claude, ChatGPT, Gemini or OpenClaw). You get a .zip with the skill already personalized: it carries a fresh key from your account, aliased with the assistant's name (e.g. "Claude skill"), revocable any time below under API tokens.

Install it.

Then attach an audio in the chat and ask for anything: "transcribe this", "make me a PDF report", "translate it to English in my voice"… The assistant runs the script and hands you back the text, or the PDF/audio it generated.

Network allowlist (Claude). The code sandbox only reaches a fixed list of domains. On a team or enterprise account an admin must allow api.uttera.ai: Organization settings β†’ Capabilities, turn on Allow network egress and add api.uttera.ai to the Domain allowlist. On individual plans (Free/Pro) this is not needed β€” the skill reaches api.uttera.ai with no allowlist change. A network error on a team/enterprise account almost always means the domain hasn't been allowed yet. The audio we generate carries the inaudible watermark required by the EU AI Act.

MCP: for Claude and tool-using agents

The Model Context Protocol (MCP) is the standard way to give an assistant tools. Instead of describing every endpoint by hand, you give it one address and it discovers on its own what Uttera can do and how to call it.

Our server lives at https://mcp.uttera.ai/mcp. You sign in with your Uttera account and paste no key: the assistant sends you to log in, and from then on calls carry your authorization and spend from your balance, on the same credits as the API.

It exposes the same capabilities as the API, already wrapped as tools: speak, transcribe, translate, summarize, tell who speaks, score a pronunciation, sound effects and music, list the voices, verify a signed report, and check what the last call cost.

To add it in a compatible client β€” Claude among others β€” look for "add MCP server" or "connector", paste https://mcp.uttera.ai/mcp, and sign in when asked. Uttera is also in the official MCP registry as ai.uttera/uttera, so many clients find it by name without pasting the address.

MCP is the recommended path for an agent: it discovers the tools and their shapes by itself, with no plaintext keys to maintain. To speak OpenAI's dialect directly, or to automate without an agent, the API and n8n still apply.
MCP only takes audio by URL. A remote MCP server cannot read files from your disk: the audio has to be at a public URL (https://…) that you give the assistant. For the most common case β€” an audio file on your computer β€” use the Skill: you attach the file in the chat and the script uploads it for you. In short: Skill for local files, MCP when the audio is already published at a URL or when you want an agent to discover the tools by itself.

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.

RepositoryWhat it is
uttera-tts-hotcoldText-to-speech server with cold and hot start. Several engines behind one API
uttera-tts-vllmThe same service on vLLM, for real concurrent load
uttera-stt-hotcoldSpeech-to-text server, same pattern
uttera-stt-vllmSpeech to text on vLLM
uttera-benchmarksThe 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.

The edge that serves this API β€” routing, quotas, billing β€” and the portal are not published. They aren't a voice engine: they're the plumbing of a business, and there's nothing in there that would be any use to anyone.

Connectors in the works

What's next, in the order people ask for it:

ConnectorWhat for
CRMSo 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 messagingThe 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.