Endpoints
Every endpoint in one place — 7 of them, grouped by task, none needing a key. Chat, models, speech in, speech out, and the live transcription stream.
Every endpoint the provider serves, grouped by what you are doing. There are 7 of them, and none needs a key of any kind — not a key to buy, not a key to paste. That is the point of the provider: nothing here can be switched off by someone else's billing decision.
GET on each endpoint are all generated from one file, src/lib/providers/endpoints.ts. If a URL here is wrong, it is wrong in exactly one place — and that place is the source of truth.How a call is shaped
Model endpoints are OpenAI-shaped, so an existing client works with a base-URL change. Speech endpoints are shaped for the job: text in and MP3 out, audio in and text out. Where an endpoint takes JSON, it takes JSON; where it takes bytes, it takes bytes.
| You want to | Call | Send |
|---|---|---|
| Chat completions — The call your app makes. | POST /api/public/zyraxon/v1/chat/completions | model, messages |
| Model catalogue — What a client reads first, to discover which models exist. | GET /api/public/zyraxon/v1/models | — |
| Provider details — What the serving pool looks like right now — modalities, concurrency, and each model's live status and context window. | GET /api/public/zyraxon/v1/provider | — |
| Integration catalogue — The same integration list this page shows, as JSON — the exact values to paste into a host app, with steps and snippets. | GET /api/public/zyraxon/v1/integrations | — |
| Text to speech — Turn an answer into audio. | POST /api/public/tts | text |
| Voice catalogue — Every voice available, with its locale and gender. | GET /api/public/tts/voices | — |
| Speech to text — one endpoint, two modes — Send a recording and get the transcript, or stream audio while the person is still speaking and get text as it is recognised. | POST /api/public/stt | language |
Talk to a model
POST /api/public/zyraxon/v1/chat/completions
The call your app makes. OpenAI chat-completions semantics, with server-sent-event streaming when you ask for it.
Returns choices[].message.content, or a stream of chat.completion.chunk objects when stream is true.
| Field | Required | What it does |
|---|---|---|
model | yes | Any id from the model catalogue, e.g. zyraxon-apex. |
messages | yes | The usual [{role, content}] array. |
stream | no | true for server-sent events. |
tools | no | OpenAI function-tool definitions; the model calls them. |
curl -sN https://zyraxonai.lovable.app/api/public/zyraxon/v1/chat/completions \
-H "Content-Type: application/json" \
-d '{
"model": "zyraxon-apex",
"stream": true,
"messages": [{ "role": "user", "content": "Hello" }]
}'- ▸The
modelvalue is a ZYRAXON name, not an upstream one. That name does not change when the pool behind it does.
GET /api/public/zyraxon/v1/models
What a client reads first, to discover which models exist. Standard OpenAI list shape, so no special handling is needed.
Returns { object: "list", data: [{ id, owned_by, … }] } — ten ZYRAXON models.
curl -s https://zyraxonai.lovable.app/api/public/zyraxon/v1/models | jq -r '.data[] | .id'
GET /api/public/zyraxon/v1/provider
What the serving pool looks like right now — modalities, concurrency, and each model's live status and context window.
Returns { models: [{ id, status, context, … }], modalities, concurrency, fleet }.
curl -s https://zyraxonai.lovable.app/api/public/zyraxon/v1/provider | jq '{modalities, concurrency, fleet}'- ▸The provider page reads this endpoint live, so a model shown as rotated there is rotated in the pool at that moment.
GET /api/public/zyraxon/v1/integrations
The same integration list this page shows, as JSON — the exact values to paste into a host app, with steps and snippets.
Returns { integrations: [{ id, name, category, fields, steps, snippets }] }.
curl -s https://zyraxonai.lovable.app/api/public/zyraxon/v1/integrations | jq -r '.integrations[] | "\(.id)\t\(.name)"'
Hear an answer
POST /api/public/tts
Turn an answer into audio. The voice follows the language of the text, so a Bengali answer is read by a Bengali voice rather than an English one sounding out Bengali letters.
Returns audio/mpeg, streamed, with X-ZYRAXON-Voice naming the voice that spoke.
| Field | Required | What it does |
|---|---|---|
text | yes | What to say, up to 5000 characters. Markdown is stripped first. |
voice | no | An exact name from the voices list, e.g. bn-BD-NabanitaNeural. Wins over locale. |
locale | no | A language, e.g. bn. Picks a voice in that language. |
# Speak text. The voice is chosen from the text's own script
# unless you name one, so a Bengali answer is read by a Bengali voice.
curl -s https://zyraxonai.lovable.app/api/public/tts \
-H "Content-Type: application/json" \
-d '{"text":"Hello from ZYRAXON.","locale":"en"}' \
-o answer.mp3
# Name the voice exactly when you want a specific one
curl -s https://zyraxonai.lovable.app/api/public/tts \
-H "Content-Type: application/json" \
-d '{"text":"আজ আকাশ পরিষ্কার।","voice":"bn-BD-NabanitaNeural"}' \
-o bengali.mp3
# What voices exist: 322 of them, across 75 languages
curl -s https://zyraxonai.lovable.app/api/public/tts/voices | jq -r '.data[] | select(.locale|startswith("bn")) | .name'- ▸Code blocks, links and Markdown are removed before speaking, so an answer is not read out character by character.
- ▸Naming
voiceexactly also skips the voice-catalogue lookup, so the first byte of audio arrives sooner.
GET /api/public/tts/voices
Every voice available, with its locale and gender. 322 voices across 75 languages.
Returns { count, languages, locales, data: [{ name, locale, gender, friendly }] }.
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-TanishaaNeuralSpeak instead of typing
POST /api/public/stt
Send a recording and get the transcript, or stream audio while the person is still speaking and get text as it is recognised. Same URL; the request itself picks the mode.
Returns Batch: { success, text, language, confidence, engine, container, duration, elapsed }. Live: server-sent events — ready, language, partial, segment, done.
| Field | Required | What it does |
|---|---|---|
language | yes | bn or bn-BD. Required in both modes — the recogniser does not detect language, so a guess would be a wrong transcript. |
file | no | Batch, multipart: the audio. Format is read from the bytes, so a mislabelled file still works. |
audio | no | Batch, JSON: base64 audio, with an optional format. |
segment | no | Live: seconds per committed chunk, default 4. |
partial | no | Live: seconds between partial updates, default 1.2. |
# A recording you already have. The format is read from the bytes, # so a mislabelled file still works. language is required — the # recogniser does not detect it, and a guess is a wrong transcript. curl -s https://zyraxonai.lovable.app/api/public/stt \ -F "file=@recording.mp3" \ -F "language=bn" \ | jq -r '.text'
- ▸Accepted containers: wav, mp3, flac, ogg, webm, and raw PCM. The format is sniffed from the first bytes, not from the Content-Type.
- ▸Live mode takes raw 16-bit mono PCM. One second at 16 kHz is 32000 bytes — a client paces its microphone by that.
- ▸A compressed container cannot be cut mid-frame, which is why live mode takes PCM: raw samples can be split at any moment without corrupting the audio.
- ▸
languageis required, not detected. Asked for English about Bengali audio the recogniser returns English-sounding words at high confidence instead of failing, so a guess produces a confident wrong answer. The caller knows which language is being spoken; the endpoint asks rather than assumes. - ▸
GETon this URL returns the contract as JSON, so a coding assistant handed the URL can read it without a human explaining it.
Errors, and what they mean
| Status | Means | What to do |
|---|---|---|
400 | The request is malformed — a missing body, bad JSON, or an upload that is not audio. | Read error in the response; it names the field. |
413 | The upload is over 25 MiB. | Split it, or use the live mode of /api/public/stt. |
422 | A required field is missing — most often language on the speech endpoint. | Send it. The endpoint does not guess. |
499 | You disconnected while the transcript was being produced. | Nothing; it is reported only so a log is complete. |
502 | The speech or model engine refused the connection. | Retry once; it is usually transient. |
Checking an endpoint is alive
Every endpoint answers a plain GET with a description of itself, so you can confirm what is deployed without reading any documentation — including the one you are reading now.
# The speech endpoint describes its own contract
curl -s https://zyraxonai.lovable.app/api/public/stt | jq '{modes, containers, limits}'
# The models the pool is serving right now
curl -s https://zyraxonai.lovable.app/api/public/zyraxon/v1/models | jq -r '.data[] | .id'
# Which voices exist, and how many
curl -s https://zyraxonai.lovable.app/api/public/tts/voices | jq '{count, languages: (.languages|length)}'