Skip to content

stt: fix API-ref response examples to match real API (DS-591 follow-up) - #360

Open
abhishekmishragithub wants to merge 1 commit into
mainfrom
fix/waves-api-ref-response-shape-audit
Open

stt: fix API-ref response examples to match real API (DS-591 follow-up)#360
abhishekmishragithub wants to merge 1 commit into
mainfrom
fix/waves-api-ref-response-shape-audit

Conversation

@abhishekmishragithub

Copy link
Copy Markdown
Collaborator

Summary

Follow-up to the merged PR #355. That PR clarified the word_timestamps gate in the description; this one aligns the schema itself with what the API actually returns. The Postman screenshot on DS-591 surfaced the drift.

What was wrong

The old schema mixed Pulse and Pulse Pro fields into a single example and used a string for speaker. Real payloads (live-verified on api.smallest.ai):

Pulse (/waves/v1/stt/?model=pulse and legacy /waves/v1/pulse/get_text):

{
  "status": "success",
  "transcription": "...",
  "words": [ { "start": 0.16, "end": 1.12, "speaker": 0, "speaker_confidence": 1, "word": "Hello,", "confidence": 0.9975 } ],
  "utterances": [ { "start": 0.16, "end": 2.88, "speaker": 0, "text": "..." } ],
  "metadata": { "duration": 5.28, "fileSize": 465740 }
}

No language, no request_id, no processing_time_ms / rtfx / num_chunks. speaker is an integer, not "speaker_0". Word entries carry speaker_confidence alongside speaker.

Pulse Pro (/waves/v1/stt/?model=pulse-pro):

{
  "status": "success",
  "transcription": "...",
  "words": [ { "word": "Hello.", "start": 0.24, "end": 1.2, "confidence": 0.9626 } ],
  "language": "en",
  "metadata": { "duration": 5.28, "processing_time_ms": 172.11, "rtfx": 30.7, "num_chunks": 1 },
  "totalBytes": 465740,
  "request_id": "36e977cf-..."
}

Pro does not diarize, so words[] entries omit speaker and speaker_confidence, and there is no utterances[] field.

Fixes in this PR

  • Word.speaker type stringinteger, example speaker_00.
  • Word.speaker_confidence added (float, 0.0–1.0, present alongside speaker on Pulse+diarize).
  • Utterance.speaker type stringinteger, same fix.
  • TranscriptionResponse.metadata: duration stays on both; fileSize marked Pulse-only; processing_time_ms + rtfx + num_chunks marked Pulse-Pro-only. All example values match live.
  • TranscriptionResponse.language and .request_id descriptions clarify they only appear on Pulse Pro.
  • totalBytes added at top level (Pulse Pro only).
  • Response examples split into named examples: so the docs explorer shows distinct real payloads for pulse-default, pulse-full (word_timestamps + diarize), and pulse-pro.
  • Legacy /waves/v1/pulse/get_text: same field-shape fixes, plus corrected the metadata.duration description from "in minutes" to seconds, and split the example into default and with-word-timestamps-and-diarize.

Audit coverage note

The user's ask was a broader "validate all example responses across API-ref pages". Scope for this PR:

  • STT (both endpoints) — fixed here.
  • Get Voices (GET /waves/v1/lightning-v3.1/get_voices) — live-checked, schema matches real API ({voices: [{voiceId, displayName, tags: {language, accent, gender, age, emotions, usecases}}]}). No change needed.
  • TTS sync — binary response, no JSON schema example to validate.
  • TTS SSE / WebSocket envelope — already reconciled in a recent drift-sync commit (base + waves-v4 override in lockstep).
  • Voice cloning list and Electron chat completions — quick live check surfaced drift on both (voice-cloning list has modelIds[] in real response, spec doesn't mention; Electron returns extra vLLM fields like refusal, annotations, audio, function_call, reasoning, stop_reason, token_ids, routed_experts, service_tier, system_fingerprint). Deferred to a follow-up PR to keep this one scoped to the reported bug + its direct STT neighbours.

Test plan

  • fern check clean
  • em-dash sweep on every diffed line clean
  • nav check passed
  • spec-drift check green
  • Live-verified on api.smallest.ai for four scenarios (Pulse default, Pulse word_timestamps+diarize, Pulse Pro, webhook async): every documented field matches actual payload keys and types
  • Preview build: eyeball the docs explorer renders the three named examples on /models/api-reference/api-reference/speech-to-text/transcribe (or the v4 path if that's what's live)

Follow-up to the merged PR #355 which clarified the word_timestamps
gate but left the schema itself drifted from what the live API returns.
DS-591 Postman screenshots showed the mismatch.

Corrected on both stt-openapi.yaml (/waves/v1/stt/) and
pulse-stt-openapi.yaml (/waves/v1/pulse/get_text):

Field-type fixes:
  - speaker: type: string, example: speaker_0
    -> type: integer, example: 0 (zero-indexed label)
  - New speaker_confidence field on word entries (float 0.0-1.0,
    present alongside speaker on Pulse with diarize=true).

Pulse vs Pulse Pro separation on the unified endpoint:
  - Pulse response is {status, transcription, words[], utterances[],
    metadata: {duration, fileSize}}. No language, no request_id, no
    processing_time_ms, rtfx, num_chunks (those are Pulse Pro).
  - Pulse Pro adds language, request_id, totalBytes at top level and
    processing_time_ms + rtfx + num_chunks inside metadata. Pro does
    not diarize, so words[] entries omit speaker/speaker_confidence
    and utterances[] is absent entirely.

Description fixes:
  - Legacy Pulse endpoint's metadata.duration said "in minutes"; it
    is seconds. Corrected.

Response examples split by scenario. The unified endpoint uses named
examples: (pulse-default, pulse-full, pulse-pro) so the docs explorer
surface distinct real payloads instead of one mixed sample. The legacy
endpoint uses named examples for default vs word_timestamps+diarize.

Live-verified on api.smallest.ai with a WAV generated via TTS. Every
scenario in the new examples matches the live payload on the
field-shape axis (values differ per request, obviously).
@github-actions

github-actions Bot commented Aug 6, 2026

Copy link
Copy Markdown

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

1 participant