> 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. # Quickstart > Transcribe pre-recorded audio files using the unified STT endpoint with Pulse or Pulse Pro This guide shows you how to convert an audio file into text using the unified Speech-to-Text endpoint. Both Pulse (multilingual, 21 streaming + 12 pre-recorded languages) and Pulse Pro (leaderboard-ranked English) live behind the same path; you pick the model with `?model=`. # Pre-Recorded Audio > Transcribe pre-recorded audio files using synchronous HTTPS POST requests. Perfect for batch processing, archived media, and offline transcription workflows. The Pre-Recorded API takes an audio file and returns a complete transcript in a single request. Send raw bytes or, for the Pulse model, a URL. ## Pick a model | If your audio is... | Use | Why | | -------------------------------------- | --------------- | -------------------------------------------------------------------------------------------- | | English, and you want highest accuracy | **`pulse-pro`** | Tied #2 on the public Open ASR Leaderboard (5.42% ESB avg WER). Pre-recorded HTTP only. | | Multilingual, or you need streaming | **`pulse`** | 21 streaming + 12 pre-recorded languages, runs on both HTTP and the live WebSocket endpoint. | See the [Pulse Pro model card](/model-cards/speech-to-text/pulse-pro) and [Pulse model card](/model-cards/speech-to-text/pulse) for full benchmarks and feature matrices. ## Endpoint ``` POST https://api.smallest.ai/waves/v1/stt/?model={pulse|pulse-pro} ``` The existing path `POST /waves/v1/pulse/get_text` continues to work alongside the new unified path. ## Authentication Head over to the [smallest console](https://app.smallest.ai/dashboard/api-keys) to generate an API key, if not done previously. Also look at the [Authentication guide](/api-reference/authentication) for more information about API keys. Include your API key in the Authorization header: ```http Authorization: Bearer SMALLEST_API_KEY ``` Browser and mobile clients should send a [short-lived access token](/api-reference/token-based-authentication) minted by your server instead of the API key. Tokens work on this endpoint but not on the older `/waves/v1/pulse/get_text` path. ## Example Request: Pulse Pro (English) Send raw audio bytes against `?model=pulse-pro`. Word timestamps add per-word timing and confidence scores; omit for higher throughput. **`cURL`** ```bash cURL # Download sample audio curl -L -o sample.wav "https://github.com/smallest-inc/cookbook/raw/main/speech-to-text/getting-started/samples/audio.wav" # Transcribe with Pulse Pro curl --request POST \ --url "https://api.smallest.ai/waves/v1/stt/?model=pulse-pro&language=en&word_timestamps=true" \ --header "Authorization: Bearer $SMALLEST_API_KEY" \ --header "Content-Type: application/octet-stream" \ --data-binary "@sample.wav" ``` **`Python`** ```python Python import os, requests API_KEY = os.environ["SMALLEST_API_KEY"] SAMPLE_URL = "https://github.com/smallest-inc/cookbook/raw/main/speech-to-text/getting-started/samples/audio.wav" audio_data = requests.get(SAMPLE_URL).content response = 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_data, timeout=120, ) response.raise_for_status() result = response.json() print(result["transcription"]) ``` **`JavaScript`** ```javascript JavaScript const endpoint = "https://api.smallest.ai/waves/v1/stt/"; const params = new URLSearchParams({ model: "pulse-pro", language: "en", word_timestamps: "true" }); const audioResponse = await fetch("https://github.com/smallest-inc/cookbook/raw/main/speech-to-text/getting-started/samples/audio.wav"); const audioBuffer = Buffer.from(await audioResponse.arrayBuffer()); const response = await fetch(`${endpoint}?${params}`, { method: "POST", headers: { Authorization: `Bearer ${process.env.SMALLEST_API_KEY}`, "Content-Type": "application/octet-stream", }, body: audioBuffer, }); if (!response.ok) throw new Error(await response.text()); const data = await response.json(); console.log(data.transcription); ``` ### Async via webhook (Pulse Pro) For long audio files where you do not want to hold an HTTP connection open, pass `webhook_url`. The endpoint returns `200` immediately with `{"status": "processing", "request_id": "..."}`; the transcription hits your webhook when ready. ```bash curl --request POST \ --url "https://api.smallest.ai/waves/v1/stt/?model=pulse-pro&language=en&webhook_url=https://your.app/cb" \ --header "Authorization: Bearer $SMALLEST_API_KEY" \ --header "Content-Type: application/octet-stream" \ --data-binary "@longcall.wav" ``` ## Example Request: Pulse (multilingual) For non-English audio, code-switching, or when you need streaming, use `?model=pulse`. Set `language` explicitly to the known code (`en`, `hi`, `es`, etc.) for best accuracy, or use a regional aggregator for unknown audio: on pre-recorded that's `multi-eu` (21 European codes + `en`) or `multi-asian` (`zh`, `ja`, `ko`, `en`). See the [Pulse model card](/model-cards/speech-to-text/pulse) for the full per-mode language matrix. ### Raw audio bytes **`cURL`** ```bash cURL curl --request POST \ --url "https://api.smallest.ai/waves/v1/stt/?model=pulse&language=hi&word_timestamps=true" \ --header "Authorization: Bearer $SMALLEST_API_KEY" \ --header "Content-Type: application/octet-stream" \ --data-binary "@hindi-sample.wav" ``` **`Python`** ```python Python import os, requests response = requests.post( "https://api.smallest.ai/waves/v1/stt/", params={"model": "pulse", "language": "hi", "word_timestamps": "true"}, headers={ "Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}", "Content-Type": "application/octet-stream", }, data=open("hindi-sample.wav", "rb").read(), timeout=120, ) response.raise_for_status() print(response.json()["transcription"]) ``` ### Audio URL (Pulse only) Pulse also accepts a URL for audio hosted in cloud storage. Pulse Pro does not support audio-by-URL. **`cURL`** ```bash cURL curl --request POST \ --url "https://api.smallest.ai/waves/v1/stt/?model=pulse&language=en&word_timestamps=true" \ --header "Authorization: Bearer $SMALLEST_API_KEY" \ --header "Content-Type: application/json" \ --data '{ "url": "https://github.com/smallest-inc/cookbook/raw/main/speech-to-text/getting-started/samples/audio.wav" }' ``` **`Python`** ```python Python import os, requests response = requests.post( "https://api.smallest.ai/waves/v1/stt/", params={"model": "pulse", "language": "en", "word_timestamps": "true"}, headers={ "Authorization": f"Bearer {os.environ['SMALLEST_API_KEY']}", "Content-Type": "application/json", }, json={"url": "https://github.com/smallest-inc/cookbook/raw/main/speech-to-text/getting-started/samples/audio.wav"}, timeout=120, ) response.raise_for_status() print(response.json()["transcription"]) ``` > **Note** > > For Pulse, set `language` explicitly to match the audio (`en`, `hi`, `es`, etc.) for the best accuracy. For unknown audio, pick the regional auto-detect scope: pre-recorded supports `multi-eu` (21 European codes + `en`) or `multi-asian` (`zh`, `ja`, `ko`, `en`). See the [Pulse model card](/model-cards/speech-to-text/pulse) for which codes each aggregator covers. ## Example Response ### Pulse Pro ```json { "status": "success", "transcription": "This is a sample audio file for testing speech-to-text transcription with the Pulse API.", "words": [ {"word": "This", "start": 0.32, "end": 0.4, "confidence": 0.9625}, {"word": "is", "start": 0.48, "end": 0.56, "confidence": 0.9344}, {"word": "a", "start": 0.64, "end": 0.72, "confidence": 0.9695} ], "language": "en", "metadata": { "duration": 5.6, "processing_time_ms": 240.51, "rtfx": 23.3, "num_chunks": 1 }, "request_id": "87dd36c1-4267-472d-96ee-4113e0a770a6" } ``` ### Pulse ```json { "status": "success", "transcription": "This is a sample audio file for testing speech to text transcription with the Pulse API.", "words": [ {"start": 0.48, "end": 1.12, "word": "This"}, {"start": 1.12, "end": 1.28, "word": "is"} ], "utterances": [ {"start": 0.48, "end": 4.96, "text": "This is a sample audio file for testing speech to text transcription with the Pulse API."} ], "metadata": { "duration": 5.6, "fileSize": 268844 } } ``` > **Tip** > > **Full runnable source files:** [Python](https://github.com/smallest-inc/cookbook/blob/main/speech-to-text/transcribe-python.py) | [JavaScript](https://github.com/smallest-inc/cookbook/blob/main/speech-to-text/transcribe-javascript.js) | [cURL](https://github.com/smallest-inc/cookbook/blob/main/speech-to-text/transcribe-curl.sh) ## Next Steps * Learn about [supported audio formats](/models/speech-to-text/pre-recorded/audio-formats). * Decide which enrichment options to enable in the [features guide](/models/speech-to-text/pre-recorded/features). * Configure asynchronous callbacks with [webhooks](/models/speech-to-text/pre-recorded/webhooks). * Review a full [code example](/models/speech-to-text/pre-recorded/code-examples) here. > Transcribe pre-recorded audio files using the unified STT endpoint with Pulse or Pulse Pro