Speech-to-Speech (STS)
Conversational speech-to-speech — the caller speaks, the agent replies with voice in real time. This is the same stack as Live talk and the dashboard Live talk studio.
STS is delivered over a WebSocket, not the REST /v1/audio/* endpoints used for TTS and STT.
Endpoints
| Purpose | URL |
|---|---|
| WebSocket | wss://platform.oogam.in/v1/realtime |
| Session meta | GET https://platform.oogam.in/api/naad/sts/v1/realtime/session |
| Voices | GET https://platform.oogam.in/api/naad/sts/voices |
| Languages | GET https://platform.oogam.in/api/naad/sts/languages |
Everything terminates on the platform: your clients only ever talk to platform.oogam.in. Each WebSocket connection is its own isolated realtime session — audio and events are never mixed across connections.
Authentication
STS uses the same platform API key (sk-setu-…) as REST TTS/STT — with the naad product enabled and credit in the project wallet. Pass it as a Bearer header:
Authorization: Bearer sk-setu-…Browser WebSockets cannot set headers, so browser clients may pass the key as a query param instead:
wss://platform.oogam.in/v1/realtime?api_key=sk-setu-…Connections are metered per actual connection second and billed to the key's project wallet at the naad-sts-v1 per-minute rate — same as Live talk in the dashboard.
Audio formats
| Direction | Format |
|---|---|
| Client → server (mic) | Binary WS frames · PCM16 LE mono @ 16 kHz |
| Server → client (agent) | Binary WS frames · PCM16 LE mono @ 24 kHz |
JSON control events share the same WebSocket.
Important differences from REST TTS/STT
- Language codes are 2-letter (
hi,en,mr) — notHIN/ENG. - Voice ids are
f1,m1, … — notaditi/arjun. List them viaGET /api/naad/sts/voices.
Call flow
GET /api/naad/sts/v1/realtime/session— confirm protocol- Open the WebSocket
- Send
set_langthenset_voice - Wait for
voice_ack - Send
start_utterance - Stream mic PCM continuously as binary frames
- Handle
state,stt,reply, and binary agent audio - On hang-up:
stop_utterance/ close the socket
Client → server events
{"type":"set_lang","value":"hi"}
{"type":"set_voice","voice":"f1"}
{"type":"set_context","system":"You are a helpful support agent…","kb_id":"kb_1","temperature":0.3}
{"type":"start_utterance"}
{"type":"stop_utterance"}
{"type":"reset"}| Event | Purpose |
|---|---|
set_lang | Pin language. Prefer a real code over auto for turn 1. |
set_voice | Pin voice (f1 = Aditi, m1 = Arjun, …) |
set_context | Optional system prompt / KB grounding (≤ 8000 chars) |
start_utterance | Begin listening |
stop_utterance | End or cancel the current turn |
reset | Clear conversation history (keeps voice / lang / context) |
Server → client events
| Event | Meaning |
|---|---|
state | idle | listening | thinking | speaking |
voice_ack | Voice pin accepted |
context_ack | Context pin accepted |
stt | Transcript. If replace: true, overwrite the last user line instead of appending. |
lang_hint | Optional hint that the caller may be speaking another language — show a switch prompt; never auto-switch. |
reply | Agent text for the turn |
interrupted | Caller barged in — stop local playback |
end | Turn finished |
error | Error with code / detail |
| binary frames | Agent audio PCM16 @ 24 kHz |
Inspect the protocol
curl -sS "https://platform.oogam.in/api/naad/sts/v1/realtime/session"
curl -sS "https://platform.oogam.in/api/naad/sts/voices"
curl -sS "https://platform.oogam.in/api/naad/sts/languages"Node example
import WebSocket from "ws";
const ws = new WebSocket("wss://platform.oogam.in/v1/realtime", {
headers: { Authorization: `Bearer ${process.env.SETU_API_KEY}` },
});
ws.on("open", () => {
ws.send(JSON.stringify({ type: "set_lang", value: "hi" }));
ws.send(JSON.stringify({ type: "set_voice", voice: "f1" }));
});
ws.on("message", (data, isBinary) => {
if (isBinary) {
// PCM16 LE mono @ 24 kHz — play to speaker
return;
}
const msg = JSON.parse(data.toString());
if (msg.type === "voice_ack") {
ws.send(JSON.stringify({ type: "start_utterance" }));
// then stream mic as binary PCM16 LE mono @ 16 kHz
}
if (msg.type === "stt") {
console.log("user:", msg.text ?? msg.value, msg.replace ? "(replace)" : "");
}
if (msg.type === "reply") {
console.log("agent:", msg.text ?? msg.value);
}
});Builtin voices
| Id | Name | Gender |
|---|---|---|
f1 | Aditi | Female |
f2 | Kavya | Female |
f3 | Meera | Female |
f4 | Isha | Female |
m1 | Arjun | Male |
m2 | Kabir | Male |
m3 | Rohan | Male |
m4 | Vikram | Male |
Offline re-voice (not conversational STS)
To re-voice a recorded file without a live call, use the REST voice changer instead:
curl https://platform.oogam.in/v1/audio/voice-changer \
-H "Authorization: Bearer $SETU_API_KEY" \
-F model="naad-s2s-v1" \
-F voice="arjun" \
-F file="@speech.wav" \
--output changed.wavSee also Audio & Voice for TTS and STT.