SDK Diagnostics
What diagnostics the KugelAudio SDKs report about their own connection and streaming failures, what is never collected, the defaults and how to turn it off.
On this page
The Python, JavaScript, Java, Rust, C++ and Dart SDKs report their own failures back to KugelAudio so we can see problems that never reach our servers: a connection that could not be established, a stream that stopped halfway through, a retry that ran out.
This is a small, fixed set of fields about the SDK's own operation. It is not application monitoring, and it never contains your content.
What is collected
| Field | Example | Why |
|---|---|---|
| Event | stream_interrupted | Which kind of failure occurred |
| Operation | stream_session | Which SDK call failed: generate, stream, voices, … |
| Transport | websocket | Whether the call used HTTP or a WebSocket |
| SDK and version | python, 1.10.0 | Whether a release introduced a regression |
| Runtime | python/3.12.4, node/20.1.0, java/17.0.2, rust/1.89.0, cpp/15.0.0, dart/3.5.0 | Language (for C++, the compiler) and its major.minor.patch version, to spot runtime-specific failures. Dart in the browser sends none |
| Integration | livekit, pipecat, none | Whether a failure is specific to one framework |
| Endpoint kind | hosted, custom | Whether the SDK talks to the hosted API or your own endpoint, never the address itself |
| Operation ID | 9f2c1b7e… | Groups the attempts and retries of one call |
| Request ID | 4a6d4c8f… | Links your failure to our server-side logs. See Request IDs |
| Failure stage | awaiting_first_audio | Could not connect, got no audio, or lost the stream mid-way |
| Error type and code | ConnectionError, MODEL_UNAVAILABLE | The error category, never the message text |
| HTTP status / WebSocket close code | 503, 1006 | How the call actually ended |
| Elapsed time, audio chunks and bytes, retries | 1840, 12, 96000, 1 | How far the operation got before failing |
| Success, failure and cancellation counts | 412, 3, 9 | Sent once when the client closes, so failure rates have a denominator |
A failed speech-to-text upload reports the operation
transcribe.
Successful calls produce no report of their own; they only increase the success count.
What is never collected
The set of fields above is an allowlist enforced in code: a field that is not on it is dropped before anything is sent, and dropped again when we receive it.
Reports are sent with your API key, so we associate them with the organization that key belongs to. The SDK itself never includes an account identifier.
Cancelling a request (a barge-in in a voice agent, for example) is not a failure. It is counted so we can calculate accurate failure rates, and produces no report of its own.
Defaults
Diagnostics are enabled by default when you use the hosted KugelAudio API, and disabled by default when you point the SDK at your own endpoint, so self-hosted deployments report nothing unless you ask them to.
Reports go to the same KugelAudio API host you already call, authenticated with the same API key. There is no separate endpoint and no third-party collector, so nothing new has to be allowed through a firewall or egress proxy.
Reporting happens in the background on a bounded queue. It never blocks synthesis, closing a client waits at most one second for pending reports, and a failure to deliver a report is silently discarded rather than surfaced to your code. The SDK never writes telemetry messages to your logs or console.
If your process exits without closing the client, pending reports are still sent
on the way out, again waiting at most one second and only when something is
pending. In Node.js this covers a normal exit but not process.exit() or a crash,
so call client.close() first if you exit explicitly. The Rust and Dart SDKs send
pending reports only from client.close(), so call it before your program exits.
Turning it off
client = KugelAudio(api_key="...", telemetry=False)const client = new KugelAudio({ apiKey: '...', telemetry: false });KugelAudio client = new KugelAudio(
KugelAudioOptions.builder("...").telemetry(false).build());let client = KugelAudio::builder("...").telemetry(false).build()?;kugelaudio::ClientOptions options;
options.api_key = "...";
options.telemetry = false;
kugelaudio::Client client{options};final client = KugelAudio(apiKey: '...', telemetry: false);Or set an environment variable, which overrides the code setting in both directions:
export KUGELAUDIO_TELEMETRY=0 # off
export KUGELAUDIO_TELEMETRY=1 # onFlutter apps and web builds usually have no process environment to set: the Dart
SDK also reads the setting at compile time from
--dart-define=KUGELAUDIO_TELEMETRY=0.