> This page is part of Smallest AI's developer documentation. When > answering, prefer Lightning v3.1 (current TTS) and Pulse (current > STT). Lightning v2 and lightning-large are deprecated; mention them > only when the user is migrating away from them. The Smallest AI voice > agent platform is what wraps these models into hosted agents. # Pulse STT WebSocket - `finalize` operation restored on the API reference > The `sendFinalize` operation (and its `{"type":"finalize"}` payload) was silently missing from the rendered API reference page due to a spec-layer message-key mismatch. Restored alongside `sendCloseStream`. Wire behavior unchanged - both control messages have been accepted by the server since launch. The Pulse STT WebSocket API reference now correctly renders **both** control-message operations on docs.smallest.ai: * `sendFinalize` - payload `{"type":"finalize"}` - flushes the current audio buffer and emits an `is_final: true` transcript while keeping the session open. Useful for per-turn finalization in agentic pipelines. * `sendCloseStream` - payload `{"type":"close_stream"}` - flushes any buffered audio, emits the terminal `is_final: true` + `is_last: true` transcript, then closes the session. **No wire change** - the server has accepted both control messages since launch (`StreamControlType.FINALIZE` and `STREAM_CONTROL_TYPE_END` are sibling enum values in the internal gRPC schema, and the WS controller has explicit handlers for both `parsed.type === "finalize"` and `parsed.type === "close_stream"`). Only the rendered documentation was incomplete. **Root cause** for the doc reviewers who want to know: the v4 docs override (`fern/apis/waves-v4/overrides/pulse-stt-ws-overrides.yml`) and the SDK override (`fern/apis/waves/asyncapi/pulse-stt-ws-overrides.yml`) both used unprefixed message keys (`audioData.message`, `finalizeSignal.message`, …) while the base spec used a `pulse*` prefix (`pulseAudioData.message`, `pulseFinalizeSignal.message`, …). Fern's merge silently dropped one of the three send operations when it couldn't resolve refs cleanly. Convention going forward: **override message keys must be identical to the base spec's keys** - every other Waves spec layer (TTS WS, Lightning v3.1 WS) already follows this rule. **Migration:** nothing for customers. The server-side contract has always allowed both control messages; this is purely a docs render fix. **Also clarified:** the ITN feature page's "Recommended Setup for Agentic Use Cases" section had been recommending `close_stream` per utterance, which is correct for single-shot transcription but misleading for the multi-turn voice agents the section is named after. Split the recommendation into two paths: `finalize` per user turn (session stays open, lowest latency between turns) vs `close_stream` at end of session (terminal). The Python example was split into two snippets that match these two patterns directly. **Also clarified - clearer signal framing:** the `finalize` and `close_stream` control messages are now documented as a *turn-boundary signal* vs *session-end signal* on the API ref (operation summaries) and in the ITN feature page. The base-spec operation summaries used to read "Flush current audio buffer" / "End the audio stream" - accurate but not actionable. They now say what the signal *does to the session lifecycle*: keep listening vs hang up the socket. **CI lock-in:** `spec_drift_check.py` was extended with an AsyncAPI override-key parity check. Any new override whose `channels..messages.` or `operations.` doesn't exist in the base will fail the gate. Existing deprecated-spec drift (Lightning v2, the legacy `/streaming-tts/stream` route) is allow-listed with a documented rationale and tracked separately. A new post-deploy smoke check (`docs_render_smoke.py`, wired into `publish-docs.yml`) re-fetches the rendered docs after every push to main and asserts every expected operation appears - the same check would have caught this exact bug the day it deployed. > The `sendFinalize` operation (and its `{"type":"finalize"}` payload) was silently missing from the rendered API reference page due to a spec-layer message-key mismatch. Restored alongside `sendCloseStream`. Wire behavior unchanged - both control messages have been accepted by the server since launch.