Markup

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

A text value whose first element is <speak> is parsed as markup. Every construct is realised for real, not treated as a hint.

<speak>
  Guete Tag.<break time="400ms"/>
  Ihri Referenz isch <say-as interpret-as="digits">4711</say-as>.
  <mark name="after_ref"/>
  <prosody rate="slow">
    Mir rüefed Sie zrugg uf <say-as interpret-as="telephone">+41 31 533 22 02</say-as>.
  </prosody>
</speak>
element effect
<break time="500ms"/> <break strength="strong"/> silence of exactly that length in the audio
<say-as interpret-as="…"> rewrites the text into its spoken form (see below)
<sub alias="Aktiengesellschaft">AG</sub> speaks the alias instead
<prosody rate pitch volume> real rate, pitch and gain change on that passage
<emphasis level="reduced|moderate|strong"> delivery directive on that passage
<lang xml:lang="de-CH-bern"> switches language and dialect mid-text
<mark name="x"/> returns the offset of that point in marks
<p> <s> paragraph (500 ms) and sentence (250 ms) pauses

prosody accepts keywords (x-slowx-fast, x-softx-loud, x-lowx-high), percentages, multipliers, -6dB, -2st.

Markup works in realtime too: a text.append whose content is a complete <speak> document is expanded into passages immediately.

Unsupported elements are rejected by name, never ignored. The response is 400 tts.invalid_ssml with an explanation in error.detail:

{"error":{"code":"tts.invalid_ssml",
          "message":"The markup could not be processed.",
          "detail":"<phoneme> is not supported: phonetic alphabets are not supported by this engine; use <sub alias=\"...\"> to respell a word",
          "request_id":"req_…"}}

<audio src> is refused deliberately: it would make our server fetch a URL of your choosing. <phoneme> is refused because no phonetic alphabet reaches the synthesis stage; use <sub alias> to respell a word.

Limits: a single pause ≤ 10 s, 60 s of pause in total, 2000 elements, 24 levels of nesting. Comments, processing instructions and DOCTYPE declarations are refused outright.

say-as: Swiss numbers in particular

interpret-as input spoken as
digits 4711 vier sibe eis eis (Zürich)
telephone +41 31 533 22 02 null drüü eis, füf drüü drüü, zwöi zwöi, null zwöi (Bern)
characters / spell-out AB7 A, Be, sibe
ordinal 15 fünfzehnte
date 2026-09-15, 15.09.2026, 09/15/2026 + format="mdy" fünfzehnter September 2026
time 14:30 14 Uhr 30
currency CHF 1250.50 1250 Franken 50 Rappen
number / cardinal 1'250 1250, handed to the voice as a numeral

Two things worth knowing:

Digits are dialect-specific. digits and telephone use a digit table and the familiar 3-3-2-2 grouping per dialect. Standard German digit words inside a Bernese utterance are audible as a register break, which is why there is a table per dialect and not one for German.

Cardinals are deliberately not expanded. number hands the numeral to the voice, which reads it correctly in dialect. Rewriting it into Standard German orthography would make it worse. Use say-as where a voice would otherwise guess wrong (identifiers, phone numbers, dates, reference codes), not everywhere.