v11

latestOpenAPI 3.0.1raw.githubusercontent.com2026-08-011518.1 KB
Speech to Text

Transcribe (Pre-recorded)

Transcribe an audio file. The model is chosen via ?model=:

  • ?model=pulse-pro: English-only, leaderboard-ranked accuracy. Raw bytes only; pass webhook_url to receive transcription asynchronously on long files.
  • ?model=pulse: multilingual transcription (21 streaming + 26 pre-recorded languages), supports both raw bytes and audio-by-URL.

When to use this

Use this endpoint when you have a complete audio file (call recording, voicemail, podcast episode) and want the transcript back in one response. For live transcription as audio arrives, use the realtime WebSocket endpoint (WS /waves/v1/stt/live) instead.

Pulse Pro has no streaming worker today; calls to WS /waves/v1/stt/live?model=pulse-pro return 400 before the WebSocket upgrades.

Input methods

  • Raw bytes: Content-Type: application/octet-stream with the audio in the body. All knobs are query parameters.
  • URL (?model=pulse only): Content-Type: application/json with {"url": "..."} in the body.

Examples

cURL: Pulse Pro, sync

curl -X POST "https://api.smallest.ai/waves/v1/stt/?model=pulse-pro&language=en&word_timestamps=true" \
  -H "Authorization: Bearer $SMALLEST_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary "@./call.wav"

cURL: Pulse Pro, async via webhook

curl -X POST "https://api.smallest.ai/waves/v1/stt/?model=pulse-pro&language=en&webhook_url=https://your.app/cb" \
  -H "Authorization: Bearer $SMALLEST_API_KEY" \
  -H "Content-Type: application/octet-stream" \
  --data-binary "@./call.wav"

Returns 200 { "status": "processing", "request_id": "..." } immediately. The webhook receives the full transcription when ready.

cURL: Pulse, audio-by-URL

curl -X POST "https://api.smallest.ai/waves/v1/stt/?model=pulse&language=en" \
  -H "Authorization: Bearer $SMALLEST_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{"url": "https://your-bucket.s3.amazonaws.com/call.wav"}'

Python

import requests

with open("./call.wav", "rb") as f:
    audio = f.read()

r = requests.post(
    "https://api.smallest.ai/waves/v1/stt/",
    params={"model": "pulse-pro", "language": "en", "word_timestamps": "true"},
    headers={"Authorization": f"Bearer {API_KEY}", "Content-Type": "application/octet-stream"},
    data=audio,
)
r.raise_for_status()
print(r.json()["transcription"])

JavaScript / TypeScript

import { readFileSync } from "node:fs";

const audio = readFileSync("./call.wav");
const params = new URLSearchParams({ model: "pulse-pro", language: "en", word_timestamps: "true" });

const res = await fetch(`https://api.smallest.ai/waves/v1/stt/?${params}`, {
  method: "POST",
  headers: { Authorization: `Bearer ${process.env.SMALLEST_API_KEY}`, "Content-Type": "application/octet-stream" },
  body: audio,
});
console.log((await res.json()).transcription);

Common gotchas

  • model is required. Missing or invalid values return 400 with an enum-validation error.
  • Pulse Pro is English only. Pass language=en. Other language codes are accepted at the wire level but produce unpredictable output.
  • Pulse Pro does not support audio-by-URL. Send raw bytes or use ?model=pulse for the URL flow.
  • Async (webhook) mode is Pulse Pro only. Pulse runs sync only on this endpoint.
  • Max payload 250 MB. Larger requests return 413. Compress to mono 16 kHz PCM if you are close to the limit; quality is unaffected.
post/waves/v1/stt/

Query parameters

model'pulse-pro' | 'pulse' required

Selects which ASR model handles the request. Required; missing or invalid values return 400.

  • pulse-pro: English only, leaderboard-ranked accuracy, raw bytes only; supports async via webhook_url.
  • pulse: multilingual (39 languages), raw bytes OR URL.
language'en' | 'hi' | 'de' | 'es' | 'ru' | 'it' | 'fr' | 'nl' | 'pt' | 'uk' | 'pl' | 'cs' | 'sk' | 'lv' | 'et' | 'ro' | 'fi' | 'sv' | 'bg' | 'hu' | 'da' | 'lt' | 'mt' | 'zh' | 'ja' | 'ko' | 'multi-eu' | 'multi-asian' | 'multi-indic' required

Language of the audio file. This endpoint is Pre-Recorded (HTTP) — for streaming, switch to WSS /waves/v1/stt/live (different supported language set).

26 single-language codes: en, hi, de, es, ru, it, fr, nl, pt, uk, pl, cs, sk, lv, et, ro, fi, sv, bg, hu, da, lt, mt, zh, ja, ko.

Regional auto-detect aggregators for unknown audio:

  • multi-eu — auto-detects across all 21 European codes plus en.

  • multi-asian — auto-detects across zh, ko, ja, en.

  • multi-indic: auto-detects across en, hi, gu, mr, bn, or. India region only.

  • Pulse Pro: pass en.

  • Pulse: pass any of the single-language codes above, or use the multi-eu / multi-asian / multi-indic aggregator for unknown audio. See the Pulse model card for the full table with language names.

word_timestampsboolean

Include the per-word words[] array in the response — each entry carries the recognized word, its start/end timestamps, and a per-word confidence score (0.0–1.0). With diarize=true, entries also include speaker. On Pulse Pro this costs roughly one-third of throughput.

diarizeboolean

Multi-speaker identification; adds per-word and per-utterance speaker labels.

webhook_urlstring uri

Pulse Pro only. If set, the response is 200 with {"status": "processing", "request_id": "..."} immediately, and the full transcription is delivered to this URL when ready. Use for long files where you do not want to hold an HTTP connection open.

webhook_method'GET' | 'POST'

HTTP method to use when calling the webhook. Pulse Pro only.

webhook_extrastring

Arbitrary metadata returned to the webhook in addition to the transcription payload. Pulse Pro only.

redact_pii'true' | 'false'

Redact personally identifiable information from the transcript. Names → [FIRSTNAME_*] / [LASTNAME_*], phone numbers → [PHONENUMBER_*], addresses → [ADDRESS_*], etc. The redaction tokens use sequential indices so multiple occurrences of the same entity get distinct labels ([FIRSTNAME_1], [FIRSTNAME_2]).

Language support: currently effective only on en and hi. Setting redact_pii=true on other language codes is accepted but does not redact.

redact_pci'true' | 'false'

Redact payment card information (credit-card numbers, CVV, account numbers, etc.). Replaces matches with [ACCOUNTNUMBER_*] tokens. Use alongside redact_pii=true for full PCI-compliant transcript handling.

Language support: currently effective only on en and hi. Setting redact_pci=true on other language codes is accepted but does not redact.

emotion_detection'true' | 'false'

When true, the response adds an emotions object mapping detected emotion labels to confidence scores. Useful for voice-of-customer analytics on call recordings.

gender_detection'true' | 'false'

When true, the response adds a gender field with the detected speaker gender label. Pulse pre-recorded only.

Request body

urlstring uri required

Example request

{
  "url": "https://example.com/audio.wav"
}

Response

Transcription succeeded. The response body has two shapes:

  • Sync: full TranscriptionResponse with transcription, words, metadata, etc. Returned when webhook_url is not set (all ?model=pulse requests, and ?model=pulse-pro requests without a webhook).
  • Async: { "status": "processing", "request_id": "..." }. Returned when ?model=pulse-pro is paired with webhook_url. The full TranscriptionResponse then arrives on the webhook when ready.
OR

Example response

{
  "status": "success",
  "transcription": "Hi, how are you doing?",
  "words": [
    {
      "word": "hello",
      "start": 0.32,
      "end": 0.4,
      "confidence": 0.96,
      "speaker": "speaker_0"
    }
  ],
  "utterances": [
    {
      "text": "Hello world.",
      "end": 0.9,
      "speaker": "speaker_0"
    }
  ],
  "language": "en",
  "metadata": {
    "duration": 5.6,
    "processing_time_ms": 240.51,
    "rtfx": 23.3,
    "num_chunks": 1,
    "filename": "audio.wav",
    "fileSize": 268844
  },
  "request_id": "87dd36c1-4267-472d-96ee-4113e0a770a6",
  "gender": "female",
  "emotions": {
    "neutral": 0.72,
    "happy": 0.18,
    "calm": 0.1
  }
}
All 1 operations