Speech: Listening and Speaking

Hear any answer aloud in its own language, and speak to the model. 322 neural voices across 75 languages, streamed as MP3 as it is written.

Every answer the ZYRAXON provider produces can be heard, not just read — and in the language the answer was written in. Ask in Bengali, and a Bengali voice reads the reply. This is the speech-to-speech loop: your speech in, the model's answer out, both in the same language.

✓
The whole feature is three endpoints
Listen: POST https://zyraxonai.lovable.app/api/public/tts — send text, get streamed MP3. Voices: GET https://zyraxonai.lovable.app/api/public/tts/voices — 322 voices across 75 languages. Speak: POST https://zyraxonai.lovable.app/api/public/stt — send a recording, get the transcript.

Hear an answer

Send the answer's text and the audio starts arriving before the sentence is finished being synthesised, so a client can begin playing almost immediately rather than waiting for a whole file.

bash
curl -s https://zyraxonai.lovable.app/api/public/tts \
  -H "Content-Type: application/json" \
  -d '{"text":"Hello from ZYRAXON.","locale":"en"}' \
  -o answer.mp3

# Play it
ffplay -nodisp -autoexit answer.mp3    # macOS: afplay   Windows: start

The same in any language

Name the language and the voice follows. A Bengali answer is read by a Bengali voice — bn-BD-NabanitaNeural — not by an English one reading Bengali letters.

bash
# Bengali
curl -s https://zyraxonai.lovable.app/api/public/tts -H "Content-Type: application/json" \
  -d '{"text":"আমি একটি ZYRAXON মডেল।","locale":"bn"}' -o bn.mp3

# Hindi, naming the voice exactly
curl -s https://zyraxonai.lovable.app/api/public/tts -H "Content-Type: application/json" \
  -d '{"text":"नमस्ते","voice":"hi-IN-SwaraNeural"}' -o hi.mp3

# Arabic
curl -s https://zyraxonai.lovable.app/api/public/tts -H "Content-Type: application/json" \
  -d '{"text":"مرحبا","locale":"ar"}' -o ar.mp3
FieldRequiredWhat it does
textYesWhat to speak. Up to 5000 characters.
voiceNoAn exact voice name from the voices list. Wins over locale.
localeNoA language or region, e.g. bn, bn-IN, en-US. Picks a voice in that language.
✓
The language is detected — you do not have to send it
The endpoint reads the script of the text you send and picks a voice for it. Bengali text is read by a Bengali voice, Devanagari by a Hindi one, Arabic by an Arabic one, and Latin script falls back to English. This is what makes a Bengali answer audible: an English voice reading Bengali does not pronounce the letters at all. Send locale only when you want to override the detection.

Speaking in real time

For a live conversation the audio must start before the answer is finished. Synthesising the whole reply first means seconds of silence. The pattern is to split the answer into sentences and speak each one as it is ready, queued in order so nothing is reordered.

typescript
// Speak an answer while it is still being written.
// A reply arrives token by token; feed the growing text and speak each
// completed sentence as it appears. The first sentence is heard while the
// model is still writing the second.
const queue: string[] = [];
let buffer = "";
let speaking = false;

async function speak(text: string) {
  const res = await fetch("https://zyraxonai.lovable.app/api/public/tts", {
    method: "POST",
    headers: { "Content-Type": "application/json" },
    body: JSON.stringify({ text }),   // the locale is detected from the text
  });
  const audio = new Audio(URL.createObjectURL(await res.blob()));
  await new Promise<void>((done) => {
    audio.onended = () => done();
    audio.onerror = () => done();
    audio.play();
  });
}

async function pump() {
  if (speaking) return;
  speaking = true;
  while (queue.length) await speak(queue.shift()!);
  speaking = false;
}

// Call this on every streamed token.
function feed(chunk: string) {
  buffer += chunk;
  // Cut after each sentence terminator, including the Bengali danda.
  let at = -1;
  for (let i = 0; i < buffer.length; i++) if (/[.!?।॥]/.test(buffer[i]!)) at = i;
  if (at >= 0) {
    queue.push(buffer.slice(0, at + 1).trim());
    buffer = buffer.slice(at + 1).trimStart();
    void pump();
  }
}

// When the answer ends, speak whatever is left.
function finish() {
  if (buffer.trim()) queue.push(buffer.trim());
  buffer = "";
  void pump();
}
ℹ
How fast is a sentence
A short sentence comes back in well under a second from this endpoint, which is what makes sentence-by-sentence playback feel like speech rather than a recording starting late.

Which voices exist

bash
curl -s https://zyraxonai.lovable.app/api/public/tts/voices | jq '{count, languages: (.languages|length)}'
# {"count": 322, "languages": 75}

# Every Bengali voice
curl -s https://zyraxonai.lovable.app/api/public/tts/voices | jq -r '.data[] | select(.locale | startswith("bn")) | .name'
# bn-BD-NabanitaNeural
# bn-BD-PradeepNeural
# bn-IN-BashkarNeural
# bn-IN-TanishaaNeural

Play it in a browser, as it streams

typescript
// The endpoint streams MP3, so playback can start before synthesis finishes.
const res = await fetch("https://zyraxonai.lovable.app/api/public/tts", {
  method: "POST",
  headers: { "Content-Type": "application/json" },
  body: JSON.stringify({ text: answer, locale: "bn" }),
});

const audio = new Audio(URL.createObjectURL(await res.blob()));
await audio.play();

Speak to the model

Record on the device, transcribe it, then send the transcript as an ordinary chat turn. That is the input half of the loop.

bash
TEXT=$(curl -s https://zyraxonai.lovable.app/api/public/stt -F "file=@recording.mp3" -F "language=bn" | jq -r '.text')

curl -s https://zyraxonai.lovable.app/api/public/zyraxon/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d "{\"model\":\"zyraxon-codex\",\"messages\":[{\"role\":\"user\",\"content\":\"$TEXT\"}]}" \
| jq -r '.choices[0].message.content'

A complete spoken conversation

Transcribe the recording, ask the model, then speak the answer back. This is the whole loop in one script.

bash
#!/usr/bin/env bash
# talk.sh — speak a question, hear the answer.
set -euo pipefail

ORIGIN="https://zyraxonai.lovable.app"
QUESTION=$(curl -s "${ORIGIN}/api/public/stt" -F "file=@$1" -F "language=bn" | jq -r '.text')
echo "You said: $QUESTION"

ANSWER=$(curl -s "${ORIGIN}/api/public/zyraxon/v1/chat/completions" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc --arg q "$QUESTION" \
        '{model:"zyraxon-apex", messages:[{role:"user", content:$q}]}')" \
  | jq -r '.choices[0].message.content')
echo "ZYRAXON: $ANSWER"

# Speak the answer in the language the question was asked in.
curl -s "${ORIGIN}/api/public/tts" \
  -H "Content-Type: application/json" \
  -d "$(jq -nc --arg t "$ANSWER" '{text:$t, locale:"bn"}')" -o reply.mp3
ffplay -nodisp -autoexit reply.mp3

What gets spoken

The endpoint speaks what a person would say, not the raw Markdown. A reply containing a code block is not read character by character — that would be unusable — so a fence becomes a short spoken note, links become their label, and the punctuation goes.

In the answerWhat is spoken
A fenced code block“A code block, 12 lines.”
[the docs](/docs/getting-started)“the docs”
A bare URL“a link”
**important**“important”
## Heading“Heading”
⚠
Speech is opt-in
Nothing is spoken unless a client asks for it. The site's own helper shows a Listen button on each answer and stays silent until it is pressed.

Which engine, and why it matters

Synthesis runs on Microsoft Edge's Read Aloud engine — the same one behind the browser feature — through the same protocol. That is what gives 322 neural voices in 75 languages with no key to buy and no per-character bill. Audio is MP3 at 24 kHz mono.

ℹ
What you receive
Content-Type: audio/mpeg, plus X-ZYRAXON-Voice naming the voice that actually spoke, so a client can show which language it chose.

Errors

StatusMeansWhat to do
400text is missing, or nothing remained after markup was removed.Send the answer's text.
413The text is over 5000 characters.Split it and speak it in parts.
502The speech engine refused the connection.Retry; it is usually transient.