> ## Documentation Index
> Fetch the complete documentation index at: https://docs.kugelaudio.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Cognigy Integration

> Use KugelAudio as a custom speech vendor or an on-prem Azure Speech container in Cognigy Voice Gateway

KugelAudio has a built-in [Cognigy Voice Gateway](https://docs.cognigy.com/voice-gateway) custom-vendor endpoint — no proxy server needed. Register KugelAudio once as a speech service in Cognigy's Self-Service Portal, then select it in your flows.

<Note>
  Cognigy's **built-in ElevenLabs provider is hosted-only** and has no custom base-URL field, so it cannot be pointed at KugelAudio. Add KugelAudio as a **custom speech vendor** instead, as described below.
</Note>

There are two ways to register KugelAudio, and they are interchangeable — pick one:

| Method | When to use it |
| - | - |
| [Custom speech vendor](#setup) | The default. One HTTP endpoint, the full KugelAudio option grammar, plain-text input. |
| [Azure Speech container](#alternative-register-kugelaudio-as-an-azure-speech-container) | Your Cognigy plan has no custom-vendor option, or your deployment is standardized on the **Microsoft Azure Speech Services** vendor. |

## Setup

### 1. Get your KugelAudio API key and a voice ID

* **API key** — open the [KugelAudio dashboard](https://kugelaudio.com/dashboard), then go to Settings → API Keys.
* **Voice ID** — open the [KugelAudio dashboard](https://kugelaudio.com/dashboard), go to Voices, pick a voice, and copy its ID. The numeric ID or the voice handle both work.

### 2. Add KugelAudio as a speech service

In the Cognigy Voice Gateway **Self-Service Portal**, go to **Speech** → **Add speech service** and choose a custom vendor.

<Steps>
  <Step title="Name the vendor">
    Pick any name, for example `kugelaudio`. You'll use this name to select the vendor in your flows.
  </Step>

  <Step title="Set the TTS HTTP URL">
    ```
    https://api.kugelaudio.com/v1/cognigy
    ```

    Cognigy appends `/synthesize/<vendor-name>` to this URL automatically — enter the base URL exactly as shown, without a trailing path.
  </Step>

  <Step title="Set the Authentication Token">
    Paste your KugelAudio API key. Cognigy sends it as an `Authorization: Bearer` header, which KugelAudio authenticates on every request.
  </Step>

  <Step title="Set the voice">
    Enter the voice ID from step 1.
  </Step>

  <Step title="Enable text-to-speech">
    Turn on **Use for text-to-speech**. Leave **Use for speech-to-text** off — this endpoint provides TTS only.
  </Step>

  <Step title="Enable streaming (recommended)">
    Turn on **Enable text-to-speech streaming** so audio starts playing while it is still being generated, instead of after the whole utterance is synthesized.
  </Step>

  <Step title="Choose the account scope">
    Select which Cognigy accounts may use this vendor, then save.
  </Step>
</Steps>

### 3. Select the vendor in your flow

Registering the vendor does not switch your flow over on its own. Set the vendor name in the **Custom** parameter of the relevant nodes — `Set Session Config`, `Say`, `Question`, `Optional Question`, or `Session Speech Parameters Config`.

<Warning>
  If you skip this step the flow keeps using whichever provider it used before, and nothing appears to change.
</Warning>

## Verify your API key first

If synthesis fails, check the key on its own before changing anything in Cognigy:

```bash theme={null}
curl "https://api.kugelaudio.com/v1/voices?limit=1" \
  -H "X-API-Key: YOUR_KUGELAUDIO_API_KEY"
```

`200` means the key is good. `401 Invalid API key` means the key is wrong, truncated, or from a different environment — a KugelAudio project key looks like `sk-kug-proj_lu_…` and is long, so a partial copy-paste is the usual cause.

## How it works

Cognigy sends one POST per utterance:

```json theme={null}
{
  "text": "Guten Tag, wie kann ich Ihnen helfen?",
  "voice": "1887",
  "language": "de-DE",
  "type": "text",
  "encoding": "linear16",
  "sample_rate": 8000
}
```

`encoding` and `sample_rate` are sent only when TTS streaming is enabled on the vendor, and they select how the audio comes back:

| Streaming | Response |
| - | - |
| Off | A complete WAV file with `Content-Length`. |
| On | `audio/wav` sent chunked — a WAV header followed by linear16 PCM at the requested sample rate, flushed as the model produces it. |

Language tags are BCP-47 (`de-DE`, `en-US`). KugelAudio uses the language part and ignores the region, so `de-DE` and `de-AT` both select German. See [Voices](/features/voices) for the languages each voice supports.

## Configure voice style and text normalization

Cognigy does not forward arbitrary option objects to custom TTS providers. To
configure KugelAudio per request, put the optional settings in Cognigy's
**Custom (Voice)** field:

```text theme={null}
<setting>[;<setting>...]

setting = voice=<voice>
        | style=<consistent|natural|expressive>
        | normalize=<true|false>
```

Existing configurations that contain only a voice ID or handle continue to
work unchanged. In configured form, `voice` is required exactly once and all
settings can appear in any order.

| Custom (Voice) value | Result |
| - | - |
| `1887` | Voice 1887 with the existing defaults. |
| `voice=1887` | The same as `1887`. |
| `voice=1887;style=consistent` | More consistent prosody. |
| `voice=1887;style=natural` | Natural prosody. |
| `voice=1887;style=expressive` | More expressive prosody. |
| `voice=1887;style=expressive;normalize=false` | Expressive prosody with text normalization disabled. |
| `normalize=false;style=expressive;voice=1887` | The same settings in a different order. |

The setting names and supported values are case-insensitive. `style` defaults
to the existing natural behavior and `normalize` defaults to `true`; unknown,
duplicate, or malformed options return a `400 VALIDATION_ERROR` instead of
silently falling back. See
[Text processing](/features/text-processing) for what normalization does.

## Audio format

| Parameter | Value |
| - | - |
| Container | WAV (RIFF) |
| Format | Linear PCM, 16-bit signed, little-endian |
| Channels | 1 (mono) |
| Sample rate | Matches `sample_rate` when streaming; otherwise 24000 Hz |

Supported sample rates are `8000`, `16000`, `22050`, `24000`, and `44100`. Cognigy Voice Gateway requests `8000` for streaming telephony audio.

## Alternative: register KugelAudio as an Azure Speech container

KugelAudio's ingress also answers the Azure Speech **on-premises container** contract, so you can register it under Cognigy's built-in **Microsoft Azure Speech Services** vendor instead of as a custom vendor. Nothing Azure runs; the URL points at KugelAudio.

<Steps>
  <Step title="Choose the vendor">
    **Speech** → **Add speech service** → Vendor: **Microsoft Azure Speech Services**.
  </Step>

  <Step title="Switch to the container">
    Leave **Use hosted Azure service** off and turn on **Use Azure Docker container (on-prem)**.
  </Step>

  <Step title="Set the container URLs">
    ```
    Container URL for TTS:  https://api.kugelaudio.com/v1/azure
    Container URL for STT:  https://api.kugelaudio.com/v1/azure
    ```

    Enter the base URL exactly as shown, with no path after it.

    Cognigy makes **both** fields mandatory even when speech-to-text is switched off. KugelAudio serves TTS at that URL; the same URL also answers the Azure recognition contract, but only as a stub that always returns `NoMatch` — see [Speech-to-text](#speech-to-text) below.
  </Step>

  <Step title="Set the subscription key">
    Paste your KugelAudio API key into **Subscription key (if required)**. Cognigy sends it as `Ocp-Apim-Subscription-Key`, which KugelAudio authenticates on every request.

    <Note>
      With streaming on, the Microsoft Speech SDK cannot set request headers on a WebSocket upgrade, so it sends the key in the **query string** instead. KugelAudio redacts it from its own logs, but an HTTP proxy or load balancer in front of KugelAudio may record the full URL — check its access-log configuration before going live.
    </Note>
  </Step>

  <Step title="Enable text-to-speech and streaming">
    Turn on **Use for text-to-speech** and **Enable text-to-speech streaming**. Leave **Use for speech-to-text** off.
  </Step>

  <Step title="Choose the voice">
    Cognigy's Azure voice list is a fixed list of Microsoft voice names and cannot show KugelAudio voices, so enter a KugelAudio voice yourself — see [Choosing a voice](#choosing-a-voice).
  </Step>
</Steps>

### Choosing a voice

The voice name arrives inside the SSML that Cognigy generates. KugelAudio reads it in this order:

| Voice name | Result |
| - | - |
| `1887` | Voice 1887. The KugelAudio voice ID or handle, entered directly. |
| `voice=1887;style=expressive` | Voice 1887 with a style preset — the same grammar as the custom vendor, described in [Configure voice style and text normalization](#configure-voice-style-and-text-normalization). |
| `de-DE-1887Neural` | Voice 1887. For fields that insist on Microsoft's `<language>-<REGION>-<Name>` shape, the digits in the name part are read as the voice ID. |
| `de-DE-KatjaNeural` | A default KugelAudio voice (`973`). A genuine Microsoft voice name has no KugelAudio equivalent, so synthesis falls back rather than failing a live call. |

<Warning>
  Leaving Cognigy's stock Microsoft voice selected works, but every call is answered by the fallback voice. Set the voice explicitly.
</Warning>

### Streaming

Both of Cognigy's code paths are served at the same URL:

| **Enable text-to-speech streaming** | What happens |
| - | - |
| On (recommended) | Cognigy opens a WebSocket to the URL and speaks the Microsoft Speech SDK protocol. Audio starts playing at KugelAudio's time-to-first-audio instead of after the whole utterance. |
| Off | Cognigy POSTs the SSML to the URL and waits for a complete audio file. |

### Audio formats

KugelAudio accepts Azure's `X-Microsoft-OutputFormat` tokens (and the equivalent WebSocket setting) at the sample rates it supports — `8000`, `16000`, `22050`, `24000` and `44100` Hz:

* `raw-*-16bit-mono-pcm` and `riff-*-16bit-mono-pcm`
* `raw-8khz-8bit-mono-mulaw` / `-alaw` and their `riff-` forms
* `audio-16khz-*-mono-mp3` and `audio-24khz-*-mono-mp3`

An unsupported token returns `400` rather than being resampled silently. Cognigy Voice Gateway asks for `raw-8khz-16bit-mono-pcm` or `audio-16khz-32kbitrate-mono-mp3`.

### Speech-to-text

The Azure recognition endpoints under `/v1/azure` exist only so Cognigy's mandatory **Container URL for STT** field validates. They always answer `NoMatch` and never transcribe.

### Azure container troubleshooting

| Symptom | Cause |
| - | - |
| `401 Invalid API key` | **Subscription key** is not a valid KugelAudio key — verify it with the [curl above](#verify-your-api-key-first). |
| Every call uses the wrong voice | The voice field still holds a Microsoft voice name, so the fallback voice answers. Enter a KugelAudio voice ID. |
| `400` mentioning an output format | Cognigy asked for a format KugelAudio does not emit — see [Audio formats](#audio-formats). |
| Audio plays only after a long pause | **Enable text-to-speech streaming** is off. |
| Speech-to-text never recognizes anything | Expected: the STT half is a stub. Turn **Use for speech-to-text** off. |
| Synthesis fails with WebSocket close `4003` (or HTTP `402` with streaming off) | Your organization is out of credit. Top up in the dashboard. |
| Synthesis fails with WebSocket close `4029` (or HTTP `429`) | Rate or concurrency limit reached — see [Limits](#limits). |

With streaming on, a failed synthesis closes the WebSocket with the [error code](/api-reference/errors) and its message instead of returning empty audio, so the synthesis fails visibly rather than playing silence on the call. Every request, including failed ones, appears on the **Logs** page of your dashboard.

## Limits

Each organization has a rate limit and a cap on concurrent generations. A live
phone deployment can hold several calls open at once, so the concurrency cap is
usually the one that matters — when it is exceeded, synthesis is rejected with
`429 RATE_LIMITED` (WebSocket close `4029` with streaming on).

Check your organization's limits in the [dashboard](https://kugelaudio.com/dashboard)
before going live, and contact us if you need them raised for production traffic.
See [Error codes](/api-reference/errors) for the exact responses.

## Regions

To keep traffic and data inside the EU, use the regional host instead:

```
https://api.eu.kugelaudio.com/v1/cognigy   # custom speech vendor
https://api.eu.kugelaudio.com/v1/azure     # Azure Speech container
```

See [Regions](/guides/regions) for the full list of endpoints.

## Troubleshooting

| Symptom | Cause |
| - | - |
| `401 Invalid API key` | The Authentication Token is not a valid KugelAudio key — verify it with the curl above. |
| `401 No credentials provided` | The Authentication Token field is empty. |
| `404 Voice not found` | The voice ID does not exist or is not accessible to your organization. |
| `400` mentioning `language` | The language is not supported by KugelAudio. |
| `400` mentioning `type` | The vendor is sending SSML. KugelAudio accepts plain text; use [prompting tags](/prompting/overview) to shape speech instead. |
| `400` mentioning a voice option | The **Custom (Voice)** grammar is invalid. Check the option spelling and use only the documented values above. |
| `405` or `404` on every request | The TTS HTTP URL is wrong. It must be the base URL `https://api.kugelaudio.com/v1/cognigy`, with no path after it. |
| Audio plays only after a long pause | Streaming is off on the vendor. Turn on **Enable text-to-speech streaming**. |
| Nothing changes after saving the vendor | The flow still points at the old provider — set the vendor name in the node's **Custom** parameter. |

Every error response carries a readable message, which Cognigy records in its logs:

```json theme={null}
{ "error": "Invalid API key", "error_code": "UNAUTHORIZED", "code": 401 }
```

See [Error codes](/api-reference/errors) for the full list.


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.