Product documentation

Everything the product does, and everything it does not.

VersionBeta
Last updated21 Sep 2026
StatusActive
Languages6 verified

00 / OverviewWhat TalkBridge is

Two to four people, each on their own device, each hearing everyone else in the language they read. Nobody declares the language they are about to speak — it is detected from the audio, on every utterance.

Each person opens the same link, types a shared room code, and chooses one thing: the language they want to read and hear. When somebody talks, their speech is cut into utterances as they go; the moment they pause, one model call transcribes the utterance, identifies its language and translates it into each language the room is reading. Everyone hears it spoken in their own language and sees both texts in the transcript.

No browser ever talks to a model provider. One server sits in the middle and holds every credential, which is why no key reaches a client and why the pages cannot tell you which vendor is behind any engine.

01 / Getting startedJoining a conversation

There is no sign-in. One shared room code, one device each.

Joining

Everyone opens the same link on their own device. Say how many of you there are — two, three or four — type your name, and press Join conversation. You are given a free place automatically; there is no station to pick and nothing to understand first.

The name is optional. Leave it blank and the others see you as "Speaker A" or "Speaker B". It is stored per place on your own device, so two tabs on one machine stay two different people.

If you want a particular place — testing with two tabs, or rejoining the one you had — Or pick a station yourself opens the individual stations directly.

The room code

Everyone must show the same room code before anything will connect. It defaults to demo. Change it to anything you like: it is what separates your conversation from anyone else's, so pick something unguessable if you care.

You do not have to read it out. From inside the room, Invite someone sends the room by email or copies a link. The link carries the code as ?room=, so opening it puts that person in your room rather than the last one they used — which is exactly what a shared address used to get wrong, silently.

A room is fixed to the size it was opened for. Someone arriving at a full room is told the size and turned away rather than displacing anyone.

Choosing your language

Set only the language you want to read and hear. There is deliberately no control for the language you are about to speak. If detection gets an utterance wrong — most likely on very short ones — the setting exists to correct the reading side, not to pre-declare the speaking side.

Talking

Tap the microphone and speak normally, pausing when you finish a thought; the pause is what tells the system your utterance is complete. The five-stage track under the button follows the current turn — listen, hear, translate, voice, deliver. Tap again to stop.

Saving the conversation

Once anything has been said, Download appears beside Clear. It saves a plain text file — every turn with who spoke, the language pair, what they said and what the others heard — named for the room and the date, so a folder of them sorts in order.

The file is assembled in your browser from what is already on screen. Nothing is uploaded to produce it, and the server has no history to send: if you clear the conversation without downloading it, it is gone.

02 / AccessGetting into the beta

The demo is open. There is no account, no password and no waiting list.

Open talkbridgeapp.manp.space, pick a room code, and share it — or send the invite link from inside the room. Nothing about you is stored: TalkBridge keeps no accounts and no conversation history, so there is nothing for a sign-in to protect.

There is no authentication, by design for this beta. Anyone who knows a room code can join that room. Pick an unguessable one if the conversation matters, and treat the service as unsuitable for anything sensitive until authentication exists — it is on the roadmap and is not built.

What you need

  • A modern browser with a microphone. Chrome, Edge and Safari are the ones this has been driven in.
  • Permission for the microphone. The page asks on arrival rather than mid-sentence, because a prompt that appears while you are talking costs the sentence.
  • Headphones if two people are in the same room, or a shared speaker will be picked up. The microphone is gated while translated audio plays, which stops the obvious loop, but headphones are cleaner.

03 / One conversationStep by step

What happens between one person finishing a sentence and another person hearing it, with times measured on the live deployment rather than a developer machine.

StepWhat happensRoughly
1Priya speaks Hindi. Her browser streams 16 kHz mono audio continuously to the server.live
2Voice detection notices she has stopped and closes the utterance. An 800 ms pre-roll of already-captured audio is prepended so the first word is not lost.~0.2 s
3One model call transcribes the audio, identifies the language as Hindi, and translates it into each language the room reads — in the same pass.1.6–2.1 s
4The text is synthesised as speech. Synthesis stops as soon as the signal goes quiet, rather than streaming the minutes of padding these models emit.1.2–1.5 s
5Text and audio are delivered to each listener. The speaker gets the same record without the audio, so she can see what was sent on her behalf.< 0.1 s
6Everyone hears it in their own language. Each listener's microphone is gated while it plays, so a shared speaker is never re-transcribed into a loop.~2.5 s total

A room with three different target languages measured 2365, 2813 and 2658 milliseconds for the same utterance — a spread of under half a second, because the translations run together rather than in a queue. An earlier build of this pipeline took 17.5 seconds; the two changes that closed most of that gap were architectural, not code optimisations. Both are described in the architecture section.

04 / FeaturesWhat is in the build

Languages

Six, and every one of them verified end to end — translated, spoken aloud, timed and listened to. The list was once nineteen; the other thirteen were catalogue entries rather than working features, because a language with no voice gets you a translation nobody can hear.

CodeLanguageNative
enEnglishEnglish
teTeluguతెలుగు
hiHindiहिन्दी
taTamilதமிழ்
knKannadaಕನ್ನಡ
mlMalayalamമലയാളം

The pages hold no list of their own — they render whatever the server's catalogue returns, so a language is added or removed in exactly one place.

In the room

  • Two to four places, fixed when the room is created and enforced by the server.
  • Names, not slot letters, carried across a reconnect and sanitised before they reach anyone else's screen.
  • One translation pass per distinct language. Three people reading English is one pass, not three.
  • Sentence-level pipelining. A long turn starts playing before its last sentence is translated, and still reads as one entry.
  • Invitations by link or email, with the room code travelling in the URL.
  • A downloadable record holding both halves of every turn, assembled in your browser.

When something degrades

Nothing fails quietly. A language the server cannot honour, an unknown voice, a provider that is down — each one arrives on the notice channel and names itself, because a silent fallback is indistinguishable, from the speaker's side, from translation being broken.

05 / ArchitectureHow it is put together

Two halves that cannot be merged

The speaker pages are a static build on a serverless host. The tunnel is a long-lived process that holds one WebSocket open per speaker for the length of a conversation — which a serverless platform cannot do at all. So the pages deploy to Vercel and the tunnel runs as a container on Render, with a hostname that survives a restart.

Everything above that split is indifferent to which host is chosen. Nothing above it works if the choice is wrong.

The fused call

Transcription, language detection and translation are one model call rather than three. Measured on the same clip against the deployment, fused returned in 1905 ms where the split path took 2363 ms — and against the pipeline's earliest shape the difference was far larger. It is the default for that reason.

Detection sits inside the same step as transcription because the language is resolved on the final transcript, never before it. Nothing downstream may start early, which is what fixes the latency budget at roughly three seconds rather than one.

One lane per language

The first working version of multi-person rooms used one pipeline per speaker, which serialises: in a three-language room English arrived at 3226 ms and Tamil at 5165 ms, so the last person paid for everyone ahead of them. It was replaced with one lane per target language, built on demand, bounded at four, and dispatched together. The same room then measured 3399 / 3554 / 3112 ms — the last listener waits for the slowest single translation, not the sum.

The seam

The browser speaks the tunnel's message types and nothing else. It holds no key and no provider endpoint, and it never branches on which vendor is behind an engine: what a control can do arrives as a capability in the catalogue the server sends. A page that greyed out a control by recognising a vendor id would have learned a fact about a provider, which is the one thing this seam exists to prevent.

Two doors, two mechanisms

The browser rule that guards the REST routes never sees a WebSocket upgrade, so the socket applies the same origin list itself before it accepts a connection. The socket is the door that spends the provider key, and for a while only the cheaper one was locked.

06 / ProtocolReference

One WebSocket per speaker. Binary frames carry audio; JSON frames carry everything else.

Endpoints

RoutePurpose
GET /healthLiveness, the provider's current state, and the rooms and peers connected
GET /api/modelsThe catalogue the settings interface renders: languages, models, voices, defaults, and what each engine can choose
GET /api/statsRooms and their occupants — what the lobby asks before taking a place
WS /wsThe tunnel itself, with room and speaker query parameters. speaker=auto asks the server for any free place

Client to server

binary frames                 raw PCM16, mono, 16 kHz — sent continuously
{"type":"settings", ...}      change anything at any time, including your name
{"type":"control", ...}       push-to-talk start and stop, when auto-detect is off
{"type":"ping", "at": ms}     round-trip measurement

Server to client

{"type":"ready", ...}         room, your place, your settings, peers, catalogue
{"type":"message", ...}       the turn: original text, translation, detected and
                              target language, timings, audio for the listener
{"type":"activity", ...}      every pipeline step, for the activity track
{"type":"peer", ...}          someone joined or left
{"type":"peer_settings", ...} the other person's settings, including their name
{"type":"notice", ...}        a degraded state, named
{"type":"settings", ...}      your own settings, after the server sanitised them

A display name travels inside settings rather than in a message type of its own, so the existing broadcast carries it with no protocol addition. It is re-announced on every connect, because the server keeps no state between connections. Since it renders verbatim on someone else's screen, the server strips control characters and caps its length rather than trusting the client: a 71-character name containing ESC, BEL and NUL comes back as 32 printable characters.

The message types are the contract. They are defined in one file on each side, and the two must change together or the ends stop agreeing.

07 / Running itOn your own hardware

Two processes. The server holds the credentials; the pages hold none.

The tunnel

cd pipecat-server
python3 -m venv .venv && source .venv/bin/activate
pip install -r requirements.txt
cp .env.example .env          # add your provider key
python run.py                 # listens on :7860

Confirm it is up: curl http://localhost:7860/health

The pages

cd talkbridge
npm install
cp .env.example .env.local    # point at http://localhost:7860
npm run dev                   # :3000

Open two windows on the same room code.

Reaching it from a second device

A second machine needs a route to your server. Any tunnel works; a quick tunnel needs no account and prints a public address. Put that address into the tunnel server field on both pages, or bake it into the build so nobody has to paste anything.

Quick tunnel addresses are temporary. They change on every restart and work only while the host machine is awake. For anything you will use more than once, host the server somewhere that runs long-lived processes and gives you a stable hostname.

Checking it works

node pipecat-server/scripts/smoke.mjs     # two speakers pair; sends no audio, costs nothing
TUNNEL=wss://your-host node pipecat-server/scripts/smoke.mjs

The full suite runs as one command and reports a total. A browser half drives a real Chromium against the deployed pages and asserts fifteen things no socket test can reach — layout at 1440 and 390 pixels, a blocked microphone naming the way out, a stale tunnel address being retired, and a turn rendering in a real page.

08 / Known limitsStated plainly

You will find these anyway. They are the same rows marked partial and roadmap on the build ledger.

The first turn after the service has slept

The tunnel runs on a free container that sleeps after about fifteen minutes idle and takes 30–60 seconds to wake. A health ping every ten minutes keeps it up most of the time, but if you are the first person into a room after a genuinely quiet spell, you will wait. A paid instance removes this entirely; it is not bought.

Synthesis covers fewer languages than transcription

Across every vendor surveyed, the set of languages that can be spoken is narrower than the set that can be transcribed and translated. That is why the catalogue lists six rather than nineteen: a language with no voice gets you a translation nobody can hear, which is worse than not offering it.

No accuracy figure is quotable yet

There is a benchmark harness with error rates, detection accuracy and cost per utterance, and it runs. Its corpus is synthesised speech and tone placeholders by its own README — unrealistically clean, and it flatters whichever vendor produced it. No number drawn from it means anything about real speakers, so none is published.

Four things only a person can settle

The opening-word buffer cannot be proven by a streamed WAV, because a file played from its first sample gives the buffer nothing to hold. Whether audio chunks join without a click needs an ear. Two people on two real devices is the only check that catches stale browser state, autoplay policy and echo together. And a cold start has to be measured after an instance has actually slept, not after a fresh deploy.

No authentication

Anyone with a room code can join it. This is deliberate for a beta that stores no history and creates no accounts, and it has to change before the service carries anything sensitive.

Short utterances are the weak case for detection

Language is resolved from the audio, and a single short word gives it least to work with. The reading-side language setting is the correction for this; there is no control that pre-declares what you are about to say, and adding one would undo the product.

09 / FAQQuestions we get asked

Do I have to say which language I am speaking?

No, and there is no control that would let you. It is detected from the audio on every utterance. You set only the language you want to read and hear.

How many people can be in a room?

Up to four. You choose the size when you open the room, and the server holds it to that — the person who does not fit is told the size rather than displacing anyone.

Does a third person cost three times as much?

No. An utterance is translated once per distinct language in the room, not once per listener. Three people reading English is one translation pass.

Do I need an account?

No. There is no sign-in, no account and no stored history. Open the link, share a room code, talk.

Is my conversation stored anywhere?

No. The server keeps nothing between connections, and the downloadable transcript is assembled in your own browser from what is already on your screen. If you clear the conversation without downloading it, it is gone.

Could my provider key end up in someone's browser?

No, and it is checked rather than asserted. Every deployed client asset is downloaded and scanned for key prefixes on each release; the count is zero. The browser also holds no provider endpoint and no vendor identity.

Can I run it on my own hardware?

Yes. Same codebase, flipped by environment variables — no code changes between the lanes. See running it yourself.

Why is the first turn sometimes slow?

The tunnel is on a free container that sleeps when idle. Warm, turns land in about 2–3 seconds; cold, the first one waits for the instance to wake. This is the hosting tier, not the pipeline.

Can I type instead of speaking?

Not today, and it is not faked in the interface. The tunnel protocol carries audio, settings, control and ping; a text turn needs both ends to carry one first, which is a protocol decision rather than a styling job.

How accurate is it?

No figure is published, because the only corpus measured against is synthesised speech. Publishing a number from it would be a number about a text-to-speech engine, not about real speakers. Real recordings are on the roadmap.