Integrate the SDK
Events and logging
While a session runs, Speechineer reports what it is doing as a stream of events. They reach your code through the session's onEvent callback (Integrate the SDK › Implementierung › Sprachsitzung anbinden › onEvent) and are mostly informational: use them for logging or a live status display.
One shape covers everything Speechineer reports, and level is what tells you how much it matters. debug, info and warning are progress — the session carries on. error means the session is over, and nothing else does. So onEvent sees failures too: it is the one callback that sees everything, and you never have to correlate two streams to find out whether a session is still alive.
Tipp
onError as a typed SpeechineerError you can catch by class, and lands in state.errors — see Integrate the SDK › Errors. Use onEvent for logging; use onError to react.The event object
Every event is one object:
code is the stable identifier to branch on, and type groups codes into families. There are two messages, for two readers: userMessage is already translated into the session's language and is what you show a person; message is English and is what you write to a log. meta carries the detail belonging to that code — retry counters, the field a validation complaint is about, the numbers on a spent allowance.
Telling the end from the noise
If you only branch on one thing, branch on level:
onEvent: (event) => {
// The one branch that matters: "error" means this session is finished.
if (event.level === "error") showBanner(event.userMessage);
else log.push(event.code, event.meta);
};Everything below error is something you can log and move on from. Codes are stable, but new ones appear over time — so ignore a code you do not know rather than treating it as a failure.
Listen for events
Listening is a single option: you pass onEvent where you build the session, next to your other callbacks, and it is called for everything that arrives. If you only want one level, onWarning, onInfo and onDebug each receive just their own — the same objects, pre-filtered. The options are the same in every framework:
const voice = useSpeechToForm({
form: intakeForm,
// Everything, errors included — level says which.
onEvent: (event) => log.push(`[${event.level}] ${event.code}`, event.meta),
// Or just one level:
onWarning: (notice) => log.warn(notice.code, notice.message),
});readonly voice = injectSpeechToForm({
form: intakeForm,
onEvent: (event) => log.push(`[${event.level}] ${event.code}`, event.meta),
onWarning: (notice) => log.warn(notice.code, notice.message),
});const session = speechineer.speechToForm({
form: intakeForm,
onEvent: (event) => log.push(`[${event.level}] ${event.code}`, event.meta),
onWarning: (notice) => log.warn(notice.code, notice.message),
});What Speechineer reports
Everything below is non-terminal — the session kept running. They are grouped by what they ask of you, because that is the only question a notice raises: most ask nothing, a few point at something in your code, and the rest are configuration behind your workspace. Terminal failures are a separate list, in Integrate the SDK › Errors.
Progress — nothing to do
The session is telling you what it is doing. Log it, or drive a status display from it.
| Code | Level | What it tells you |
|---|---|---|
| STOP_RECORDING_REQUESTED | info | The stop your page sent arrived — the recording is winding down. |
| CLIENT_DISCONNECTED | info | A connection from your page went away. The session itself stays alive, so this is the notice, not the end. |
| USAGE_METERED | debug | Usage was recorded for what the session has done so far. |
| LAYER_TRIGGERED | debug | A step of the session's work started — fine-grained progress, for a debug log. |
| SCOPE_STOP_REQUESTED | debug | Part of the session was asked to stop. |
| FORCE_STOP_REQUESTED | debug | The session was asked to stop immediately rather than wind down. |
Recovering — nothing to do, but worth logging
Something failed and is being retried in place. The session keeps running; if the retries give out you get an error instead, and that one ends it.
| Code | Level | What it tells you |
|---|---|---|
| TRANSCRIPTION_DOWN | warning | The transcription connection dropped and is being re-established. The attempt counters are on meta. |
| TRANSCRIPTION_SEND_FAILED | warning | A piece of audio could not be handed over and is being resent after reconnecting. Same counters as above. |
| EXTRACTION_DOWN | warning | A field-extraction attempt failed and is being retried on the latest transcript. |
Something in your code — the session carried on without it
Speechineer refused one thing your page did and kept the session running. Each of these is worth fixing: the session survived, but what you asked for did not happen.
| Code | Level | What it tells you |
|---|---|---|
| WEBSOCKET_KIND_UNSUPPORTED | warning | A connection was opened that this capability does not use, so that connection was closed — meta names which. Open only the connections the session answer lists. |
| CLIENT_FRAME_UNREADABLE | warning | Something your page sent on a connection could not be read and was ignored: not text, not valid JSON, or not a message this session accepts. meta.reason says which, and meta.accepted lists what it does accept. Nothing was acted on. |
| PRECONDITION_UNMET | warning | An action was called before the thing it needs had happened. The call itself was refused; this is the notification. |
| CODE_VALUE_OVERRIDDEN | warning | A value your code passed was overridden by the form's own configuration, which owns that setting. meta names it. Drop it from the call to stop seeing this. |
Your workspace's configuration — ours to fix, or an operator's
A capability could not be resolved from the configuration behind your workspace, so the session ran without it. Nothing in the request changes any of these: they are settings in Speechineer. Send us the code if you do not have an operator.
| Code | Level | What it tells you |
|---|---|---|
| UNIT_MAPPING_INCOMPLETE | warning | Some of what this session can produce has no price attached yet, so that part cannot be metered. |
| PROVIDER_UNRESOLVED | warning | Nothing at all could be selected for a capability the session wanted. |
| PROVIDER_INACTIVE | warning | The capability itself is switched off. |
| PROVIDER_CONFIG_INACTIVE | warning | The model configuration that was selected is deactivated. |
| PROVIDER_CONFIG_DEPRECATED | warning | The selected configuration is deprecated and the move to its replacement did not work. |
| PROVIDER_CONFIG_RETIRED | warning | The selected configuration is retired, with nothing named to replace it. |
| PROVIDER_CONFIG_NOT_ALLOWED | warning | The configuration exists but is not enabled for this workflow. If you pinned a model by name, that is the one to check. |
| PROVIDER_CONFIG_PARAM_MISSING | warning | The configuration does not supply everything the model it names requires. |
| PROVIDER_MODEL_INACTIVE | warning | The model behind the configuration is deactivated. |
| PROVIDER_MODEL_VENDOR_INACTIVE | warning | Whoever built the model is deactivated, so none of their models can be selected. |
| PROVIDER_SERVICE_VENDOR_INACTIVE | warning | Whoever serves the model is deactivated, so it cannot be reached. |
| PROVIDER_CONNECTOR_INACTIVE | warning | The credentials for that service are deactivated. |
| PROVIDER_CONNECTOR_KEY_MISSING | warning | No credential is stored for that service, so nothing could authenticate. |
| PROVIDER_ADAPTER_INACTIVE | warning | The integration for that capability is deactivated. |
| PROVIDER_ADAPTER_MISMATCH | warning | The integration does not match the capability its configuration claims. |
Additional information in