Partial tokens while the sentence is still being spoken.
Tapra-Voice-Realtime is the streaming twin of Tapra-Voice: same code-switching behaviour, different delivery. The browser or your server opens one socket, ships 16 kHz PCM frames, and receives partial events as words are recognized, then a final transcript with the exact usage charge when you stop.
ready 0.01 s → first partial 1.97 s → utterance 23.64 s → final 28.06 s (reason: client_stop)
Live output
Real output
Recorded from the live model.
Every output on this page came from tapra-voice-v1-realtime on 8 October 2026 and is shown unedited, mistakes included. Each live response also carries its exact charge in x-tapra-cost-tnd.
The 26-second code-switched voice note, streamed at real-time pace in 100 ms PCM frames. Every partial below is the event the server sent, at the moment it sent it.
0:00 / 0:00
Client sends · pcm_s16le 16 kHz
Server partials
final
نخمم نعمل une combinaison ما بين les deux modèles tomes canagent اللي هو capable يجاوب عل les clients كيما مثلا في الكنفيرما متاع les ordres والا تعمل marketing لهنا le modèle لازمو يكون قادر يعمل switch between languages ويجاوب زادا بنفس ال façon
Unedited stream. It mishears the same product name as the batch model ("tomes canagent"), and gets façon right where the batch transcript did not.
What it does
Capabilities you can build on today.
01
Silence VAD and turn endpointing
Live sessions mask silence before the decoder and emit an utterance event after about 800 ms of trailing pause. About 10 seconds of continuous silence auto-stops the session so idle microphones stop holding an ASR slot. Pass idle_stop=0 to keep listening.
02
No GPU cold start
Inference runs on commodity CPU instances. The first frame is served immediately: there is no warm-up window and no capacity you rent while idle.
03
Auth without leaking keys
Browser clients pass the WebSocket subprotocols tapra-realtime and tapra-auth.<API_KEY>. Server clients use Authorization: Bearer during the upgrade. Keys never belong in a URL.
04
Explicit session lifecycle
A ready event opens the session, partial events stream, {"type":"stop"} closes it with the final transcript and charge, and a ping every 15 seconds keeps connections alive when you are not sending audio. Ten seconds of silence also closes the session unless you pass idle_stop=0.
Integrate
The contract, in one place.
Model id
tapra-voice-v1-realtime
Endpoint
WSS /v1/realtime/stream?language=ar-AR
Client to server
Binary mono PCM frames, pcm_s16le, 16 kHz
Server to client
ready, partial, utterance, final, error events
Custom protocols
tapra-realtime, tapra-auth.<API_KEY>
VAD / endpointing
On by default; trailing silence ~800 ms emits utterance
Idle auto-stop
On by default; ~10 s of silence sends final and closes the socket
Keep-alive
{"type":"ping"} every 15 seconds when not sending audio
Close
{"type":"stop"} or idle auto-stop returns the final transcript and usage
Billing
Audio milliseconds streamed at 0.300 TND / min
Open a realtime streamts
const socket = new WebSocket(
'wss://api.tapra.tn/v1/realtime/stream?language=ar-AR',
['tapra-realtime', 'tapra-auth.' + apiKey]
);
socket.onmessage = (event) => {
const message = JSON.parse(event.data);
if (message.type === 'partial') render(message.text);
if (message.type === 'utterance') lockTurn(message.turn_text);
if (message.type === 'final') console.log(message.text, message.usage);
};
// Push mono 16-bit PCM frames, then close the session cleanly.
socket.onopen = () => recorder.onFrame((frame) => socket.send(frame));
stopButton.onclick = () => socket.send(JSON.stringify({ type: 'stop' }));
Comparison
How Tapra-Voice-Realtime differs.
Compared with GPU-hosted realtime APIs and browser speech engines.
Tapra-Voice-Realtime compared with a generic alternative
Capability
Tapra-Voice-Realtime
Generic alternative
Partial decode time
Median 4 ms, p95 119 ms across 196 partials (recorded session)
GPU warm-up curve; cold sessions stall for seconds
Idle cost
Zero — metered on streamed audio only
Reserved GPU capacity billed while quiet
Code-switching mid-stream
Darija, French, and English in one socket
Locked to one language per session
Browser auth
WebSocket subprotocols, key never in the URL
Query-string tokens that end up in logs and referrers
Consistency with batch
Same family as tapra-voice-v1, same transcript style
Separate streaming model with different conventions
Cost
0.300 TND / min (≈ $0.100), metered per session
Per-minute floors and concurrency minimums
Pricing
Metered, never subscribed.
You pay for exactly what you send. The same prepaid balance covers all five Tapra models, billed in TND.
Headline rate
0.300 TND / min
One WebSocket that revises the transcript while you speak, then locks each turn after a pause. No idle infrastructure to pay for.
Send the subprotocols tapra-realtime and tapra-auth.<API_KEY> when opening the socket. Never put a key in the query string — it would land in server logs and referrer headers.
What audio format does the socket expect?
Binary mono PCM frames encoded as pcm_s16le at 16 kHz. That is what the Tapra microphone capture already produces, so there is no resampling step.
What happens if the connection goes idle?
Send {"type":"ping"} every 15 seconds if you are not sending audio. After a pause of about 800 ms the server emits utterance and keeps listening. About 10 seconds of silence auto-stops the session (final with reason idle_stop) so it stops consuming a slot. Pass idle_stop=0 to disable that. When you are done, send {"type":"stop"} for the final transcript and usage charge.