> 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 Waves 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 + 26 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 + 26 pre-recorded languages, runs on both HTTP and the live WebSocket endpoint. |

See the [Pulse Pro model card](/models/model-cards/speech-to-text/pulse-pro) and [Pulse model card](/models/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](/models/api-reference/authentication) for more information about API keys.

Include your API key in the Authorization header:

```http
Authorization: Bearer SMALLEST_API_KEY
```

## 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.

```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
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
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](/models/model-cards/speech-to-text/pulse) for the full per-mode language matrix.

### Raw audio bytes

```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
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.

```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
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"])
```

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](/models/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
  }
}
```

**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/documentation/speech-to-text-pulse/pre-recorded/audio-formats).
* Decide which enrichment options to enable in the [features guide](/models/documentation/speech-to-text-pulse/pre-recorded/features).
* Configure asynchronous callbacks with [webhooks](/models/documentation/speech-to-text-pulse/pre-recorded/webhooks).
* Review a full [code example](/models/documentation/speech-to-text-pulse/pre-recorded/code-examples) here.