openapi: 3.0.1 info: title: Pulse ASR API description: 'API for speech-to-text conversion using the Pulse ASR model. Upload audio files and receive transcribed text using the Pulse model. ' version: 1.0.0 servers: - url: https://api.smallest.ai description: Waves API server x-fern-server-name: waves paths: /waves/v1/pulse/get_text: post: tags: - Speech to Text summary: Convert speech to text description: | Transcribe an audio file to text using the Pulse model. The fastest way to get a transcript when you already have a recording — pass either the raw bytes or a 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 (`WSS /waves/v1/pulse/get_text`) instead. ## Input methods Send the audio in one of two ways: 1. **Raw bytes** — `Content-Type: application/octet-stream` with the audio in the body. All knobs (`language`, `word_timestamps`, etc.) are query parameters. 2. **URL** — `Content-Type: application/json` with `{"url": "..."}` in the body. Useful when the audio already lives in object storage. Same query parameters apply. Pulse autodetects the language across 30+ supported locales. Pass `language` explicitly when you already know it — detection is fast but skipping it is faster. ## Examples **cURL** (raw bytes) ```bash curl -X POST "https://api.smallest.ai/waves/v1/pulse/get_text?language=en&word_timestamps=true" \ -H "Authorization: Bearer $SMALLEST_API_KEY" \ -H "Content-Type: application/octet-stream" \ --data-binary "@./call.wav" ``` **cURL** (URL) ```bash curl -X POST "https://api.smallest.ai/waves/v1/pulse/get_text?language=en" \ -H "Authorization: Bearer $SMALLEST_API_KEY" \ -H "Content-Type: application/json" \ -d '{"url": "https://your-bucket.s3.amazonaws.com/call.wav"}' ``` **Python** (`pip install smallestai>=4.4.0`) ```python from smallestai import SmallestAI client = SmallestAI(api_key="YOUR_API_KEY") with open("./call.wav", "rb") as f: result = client.waves.transcribe_pulse( request=f.read(), language="en", word_timestamps=True, diarize=True, ) print(result.status) # "success" print(result.transcription) # the transcript string ``` **JavaScript / TypeScript** (using `fetch`) ```typescript import { readFileSync } from "node:fs"; const audio = readFileSync("./call.wav"); const params = new URLSearchParams({ language: "en", word_timestamps: "true", diarize: "true" }); const res = await fetch(`https://api.smallest.ai/waves/v1/pulse/get_text?${params}`, { method: "POST", headers: { Authorization: `Bearer ${process.env.SMALLEST_API_KEY}`, "Content-Type": "application/octet-stream", }, body: audio, }); const result = await res.json(); console.log(result.transcription); ``` ## Common gotchas - **Max file size is 250 MB.** Larger files return HTTP `413`. Compress to mono 16 kHz PCM if you're close to the limit; quality is unaffected. - **Formatting flags (`format`, `punctuate`, `capitalize`)** are accepted at the wire level and exposed in the Python SDK as of `smallestai>=4.4.0`. Today they currently return the same transcript regardless of value — pass them in your integration so it works as the behavior changes. - **Webhook-driven flow**: pass `webhook_url` to receive the transcript asynchronously. The endpoint returns immediately; the transcript hits your webhook when ready. Useful for long files where you don't want to hold an HTTP connection open. - **Speaker diarization** (`diarize=true`) adds latency. Skip it if you only need the words. - **JavaScript / TypeScript**: the official `smallestai` npm package predates the Pulse model, so call this endpoint with `fetch` or `axios` as shown above. operationId: speechToText security: - BearerAuth: [] requestBody: required: true content: application/octet-stream: schema: type: string format: binary description: Raw audio bytes. Content-Type header should specify the audio format (e.g., audio/wav, audio/mp3). All parameters are passed as query parameters. application/json: schema: type: object properties: url: type: string format: uri description: URL to the audio file to transcribe. Must be publicly accessible example: https://example.com/audio.mp3 required: - url example: url: https://example.com/audio.mp3 parameters: - name: language in: query required: false schema: type: string enum: - it - es - en - pt - hi - de - fr - uk - ru - kn - ml - pl - mr - gu - cs - sk - te - or - nl - bn - lv - et - ro - pa - fi - sv - bg - ta - hu - da - lt - mt - multi - multi-eu - multi-indic - multi-asian default: multi-eu description: 'Language of the audio file. Set explicitly to the known language for best accuracy. Auto-detection scopes: - `multi-eu` (default) — European set: de, en, fr, it, nl, pt, ru, es. - `multi-indic` — Indic set: en, hi, mr, pa, gu, or, ka, ta, te, ml, bn. - `multi-asian` — East Asian set: en, ja, ko, zh, yue. - `multi` — full multilingual auto-detection across all supported languages. Omitting `language` routes to `multi-eu`, which can mis-detect on non-European audio. Always pass `language` explicitly when the source language is known, or pick the regional `multi-*` scope that matches your audio. ' - name: encoding in: query required: false schema: type: string enum: - linear16 - linear32 - alaw - mulaw - opus - ogg_opus description: | Audio encoding of the bytes you upload. Mirrors the `encoding` parameter on the realtime WS endpoint. - `linear16`, `linear32` — raw PCM (16-bit and 32-bit) - `alaw`, `mulaw` — 8 kHz telephony codecs - `opus`, `ogg_opus` — Opus compressed audio (raw and Ogg container) When omitted, the server detects the format from the file's container header (works for `.wav`, `.mp3`, `.flac`, `.ogg`, `.m4a`, `.webm`). - name: webhook_url in: query required: false schema: type: string format: uri description: URL to the webhook to receive the transcription results example: https://example.com/webhook - name: webhook_extra in: query required: false schema: type: string description: Extra parameters to pass to the transcription. These will be added to the request body as a JSON object. Add comma separated key-value pairs to the query string. eg "custom_key:custom_value,custom_key2:custom_value2" example: custom_key:custom_value,custom_key2:custom_value2 - name: word_timestamps in: query required: false schema: type: boolean default: false description: Whether to include word and utterance level timestamps in the response - name: diarize in: query required: false schema: type: boolean default: false description: Whether to perform speaker diarization - name: gender_detection in: query required: false schema: type: string enum: - 'true' - 'false' default: 'false' description: Whether to predict the gender of the speaker - name: emotion_detection in: query required: false schema: type: string enum: - 'true' - 'false' default: 'false' description: Whether to predict speaker emotions - name: format in: query required: false schema: type: string enum: - 'true' - 'false' default: 'true' description: 'Master formatting switch for the transcript. When `false`, forces `punctuate=false`, `capitalize=false`, and also disables Inverse Text Normalization (ITN) so it cannot silently reintroduce punctuation or casing. When `true`, the `punctuate` and `capitalize` params take effect independently. Leave `format=true` and use those two to fine-tune. ' - name: punctuate in: query required: false schema: type: string enum: - 'true' - 'false' default: 'true' description: 'When `false`, strips end-of-sentence punctuation (`.`, `,`, `?`, `!`) from the transcript, `words[].word`, and `utterances[].transcript`. Does not affect casing — use `capitalize` for that. Overridden to `false` when `format=false`. ' - name: capitalize in: query required: false schema: type: string enum: - 'true' - 'false' default: 'true' description: 'When `false`, lowercases the entire transcript output (transcript, `words[].word`, and `utterances[].transcript`). Does not affect punctuation — use `punctuate` for that. Overridden to `false` when `format=false`. ' responses: '200': description: Speech transcribed successfully content: application/json: schema: type: object properties: status: type: string description: Status of the transcription request example: success transcription: type: string description: The transcribed text from the audio file example: Hello world. audio_length: type: number description: Duration of the audio file in seconds example: 1.7 words: type: array description: Word-level timestamps in seconds. items: type: object properties: start: type: number example: 0.0 end: type: number example: 0.5 speaker: type: string description: Speaker if diarization is enabled example: speaker_0 word: type: string example: Hello utterances: type: array description: List of utterances with start and end times items: type: object properties: text: type: string example: Hello world. start: type: number example: 0.0 end: type: number example: 0.9 speaker: type: string description: Speaker if diarization is enabled example: speaker_0 gender: type: string description: Predicted gender of the speaker if requested example: male enum: - male - female emotions: type: object description: Predicted emotions of the speaker if requested properties: happiness: type: number format: float example: 0.8 sadness: type: number format: float example: 0.15 disgust: type: number format: float example: 0.02 fear: type: number format: float example: 0.03 anger: type: number format: float example: 0.05 metadata: type: object description: Metadata about the transcription properties: filename: type: string description: Name of the audio file example: audio.mp3 duration: type: number description: Duration of the audio file in minutes example: 1.7 fileSize: type: number description: Size of the audio file in bytes example: 1000000 example: status: success transcription: Hello world. words: - start: 0.0 end: 0.5 speaker: speaker_0 word: Hello - start: 0.6 end: 0.9 speaker: speaker_0 word: world. utterances: - text: Hello world. start: 0.0 end: 0.9 speaker: speaker_0 gender: male emotions: happiness: 0.8 sadness: 0.15 disgust: 0.02 fear: 0.03 anger: 0.05 metadata: filename: audio.mp3 duration: 1.7 fileSize: 1000000 '400': description: Bad request - Invalid parameters or file format content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: 'Invalid file format. Supported formats: audio/*' '401': description: Unauthorized - Invalid or missing authentication content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: Unauthorized - Invalid API key '413': description: Payload too large - File size exceeds limit content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: '413' message: File size exceeds maximum limit of 250MB status: error '429': description: Too many requests - Rate limit exceeded content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: code: '429' message: Rate limit exceeded. Please try again later. status: error '500': description: Internal server error content: application/json: schema: $ref: '#/components/schemas/ErrorResponse' example: error: Internal server error components: securitySchemes: BearerAuth: type: http scheme: bearer bearerFormat: JWT description: 'API key authentication using Bearer token format. Include your API key in the Authorization header as: `Bearer YOUR_API_KEY` ' schemas: ErrorResponse: type: object properties: error: type: string description: Error message describing what went wrong required: - error