Text-to-speech

Base URL https://api.suisse-speech.ch/v1 · X-API-Key

3.0 Speech models (studio vs swift)

Two models serve different use cases:

model mode description default
studio Batch Highest fidelity and natural delivery. Renders Swiss German dialect with its own wording and grammar, with nuanced expressive delivery. Recommended for IVR prompts, greetings, announcements and high-quality voice content. Yes
swift Batch and realtime Low latency. Streams audio while it is synthesised; first audio typically arrives in about half a second, and in under a second for Swiss German dialect. Made for interactive telephone agents and conversational WebSocket streams. No

studio renders the whole passage before returning audio, so the realtime stream uses swift.

3.1 Batch: POST /tts

Send the whole text, get the whole audio.

{
  "text": "Ihr Termin am Dienstag um zehn Uhr ist bestätigt.",
  "voice": "lea",
  "language": "de-CH",
  "dialect": "bern",
  "speed": 0.95,
  "style": "ruhig und geduldig, kurze Pausen nach jedem Satz",
  "format": "mp3"
}

The response body is the audio, with metadata in headers:

header meaning
X-Suisse-Request-Id quote this in support requests
X-Suisse-Audio-Duration seconds, the unit you are billed in
X-Suisse-Audio-Encoding mp3, wav, …
X-Suisse-Audio-Sample-Rate Hz
X-Suisse-Voice voice actually used
X-Suisse-Cache always miss: no audio is stored (kept for compatibility)

Add "output": "json" (or send Accept: application/json) for a JSON envelope with base64 audio, the mark offsets and the passage count instead.

3.2 Realtime: GET /tts/stream (WebSocket)

Push text as you produce it and receive audio while the rest is still being written. Use this when the text comes from a live source: an LLM, an agent, an operator typing. For text you already hold in full, batch is simpler and no slower overall.

Endpoint: wss://api.suisse-speech.ch/v1/tts/stream

Client → server

{"type":"session.start","voice":"anna","language":"de-CH","dialect":"zurich",
 "speed":1.0,"style":"freundlich","format":"pcm16","sample_rate_hz":24000}
{"type":"text.append","text":"Grüezi. "}
{"type":"text.flush"}
{"type":"session.end"}

Text is rendered passage by passage at sentence boundaries. text.flush forces a partial passage out without ending the session. Use it when you know no more text is coming for a while and you would rather have the audio now.

Server → client

{"type":"session.ready","request_id":"req_…","voice":"anna","encoding":"pcm16",
 "sample_rate_hz":24000,"frame_bytes":4096}
{"type":"audio.chunk","seq":1,"encoding":"pcm16","sample_rate_hz":24000,"data":"<base64>"}
{"type":"segment.done","characters":42,"duration_seconds":2.31,"cache":"miss"}
{"type":"mark","name":"after_ref","offset_seconds":7.15}
{"type":"session.complete","duration_seconds":7.94,"frames":48,"cache":{"hits":0,"misses":3}}

Concatenate the decoded data values in seq order to reconstruct the stream. Every frame is exactly frame_bytes except the last.

Binary transport: a third fewer bytes

Add "transport":"binary" to session.start and audio arrives as raw binary WebSocket frames instead of base64 inside JSON. Control frames stay JSON, so the rule is simple: a binary frame is always audio, in order, in the encoding session.ready named. No parsing, no decode step.

Measured on the same text: JSON transport carries 36.4 % overhead on the wire, binary carries 0.1 %.

ws.send(JSON.stringify({ type: 'session.start', voice: 'anna',
                         format: 'pcm16', transport: 'binary' }));

ws.on('message', (data, isBinary) => {
  if (isBinary) return audio.write(data);       // audio, in order
  const frame = JSON.parse(data.toString());    // control
});

transport defaults to json. Use binary for anything carrying real volume.

Reconnection. A session is not resumable. If the socket drops, open a new one and resend the text that was not yet acknowledged by a segment.done. Sessions are capped at 15 minutes.

3.3 Voices

Twelve voices, all usable in every supported language. GET /tts/voices returns the catalogue with gender, timbre, pace and a suggested use for each.

voice voice
anna warm, balanced; the default stefan neutral, professional
vera bright, energetic; menus and prompts reto deep, calm; announcements
lea soft, calm; long explanations lukas brisk, direct; confirmations
nora clear articulation; narrow-band lines jonas full-bodied, steady; corporate audio
mia gentle, empathetic; sensitive topics andrin warm, patient; advice and sales
elin neutral, even; long documents felix expressive; follows style prompts closely

Voices are stable identifiers: a voice will not be removed or repointed at a different sound without notice, because that would silently change the audio in a deployed IVR.

3.4 Languages and dialects

The catalogue has two levels. language is a code that may carry a region, and a regional standard variety is its own code: it-CH, fr-CA, en-GB, en-IN, de-AT. dialect is a variety inside one language: de-CH + stgallen, fr-CH + geneve, en-GB + scottish. GET /capabilities is the list; the hand-tuned Swiss German dialects are:

dialect region / description
standard Supra-regional Swiss German (default)
zurich Zürich (Züritüütsch)
bern Bern (Bärndütsch)
basel Basel (Baaseldütsch)
luzern Lucerne and Central Switzerland (Lozärnerdütsch)

Both models translate the input text into authentic regional dialect vocabulary, grammar and pronunciation: a real dialect, not an accent. swift does it in real time on the stream; studio does it with the highest fidelity and is the one to use for prepared audio.

language: "de-CH-zurich" is accepted as a compact equivalent of the two fields.

Switzerland comes first in the catalogue:

language dialects what you hear
de-CH standard, zurich, bern, basel, luzern Swiss German, hand-tuned
de-CH stgallen, thurgau, schaffhausen, appenzell, glarus, graubuenden, aargau, solothurn, oberland, freiburg, wallis, zug, schwyz, uri further Swiss German regions
de-CH hochdeutsch Swiss High German: Standard German with Swiss pronunciation
fr-CH none, or geneve, vaud, valais, neuchatel, fribourg, jura Swiss French and the accents of the Romandie
it-CH none Swiss Italian (Ticino)

Swiss German dialects are rendered INTO the dialect (wording, grammar and sound) so reply text may be written in Standard German. Every other variety, Swiss High German included, keeps the words exactly as written and changes only pronunciation, melody and rhythm.

Beyond Switzerland the larger languages carry their regional standard varieties as language codes, some with accents of their own as dialects: de-DE, de-AT, fr-FR, fr-BE, fr-CA, it-IT, en-GB, en-US, en-IE, en-AU, en-IN, es-ES, es-MX, pt-PT, pt-BR, nl-BE and more. Read them from GET /capabilities rather than from this page.

Every language and every dialect carries a status. The five hand-tuned Swiss German dialects and Swiss French are verified: we run and measure them in production. Everything else in the tables above is supported: rendered on a best-effort basis, with no published quality figure. Listen before you commit a supported variety to production. A delivery the catalogue does not list at all (another accent, a register) can be asked for in free text with style (3.6), equally on a best-effort basis.

3.5 Audio formats

format container rates (Hz) use
mp3 MPEG 32000, 44100, 48000 general purpose, small
wav RIFF 8000 … 48000 (24000) lossless, easy to post-process
opus Ogg 48000 lowest bandwidth for streaming
pcm16 none 8000 … 48000 (24000) lowest latency, feed straight to a mixer
mulaw none 8000 G.711 µ-law, drop-in for a telephony trunk
alaw none 8000 G.711 A-law, drop-in for a telephony trunk

Defaults in bold. pcm16, mulaw and alaw are headerless: you get raw samples, which is what a telephony stack usually wants.

3.6 Style

style is a free-text delivery prompt. It steers how the text is spoken, never what is spoken: the supplied text is always rendered verbatim.

"freundlich und zügig, wie am Empfang"
"ruhig und geduldig, kurze Pausen nach jedem Satz"
"sachlich und neutral, ohne Emotion"

3.7 Long text

Batch and realtime both hold a connection for the length of the work. For a chapter rather than a sentence, submit a job instead.