> ## Documentation Index
> Fetch the complete documentation index at: https://docs.suonora.com/llms.txt
> Use this file to discover all available pages before exploring further.

# Stream Speech

> Converts text to speech and streams MP3 audio in real-time

<OpenApiPlayground />

<CardGroup cols={2}>
  <Card title="Endpoint" icon="code" iconColor="blue">
    <code>POST /v1/audio/stream</code>
  </Card>

  <Card title="Authentication" icon="lock" iconColor="green">
    Bearer token required
  </Card>
</CardGroup>

## Overview

The streaming endpoint converts text to speech and streams MP3 audio in real-time. This endpoint is ideal for applications requiring low-latency audio playback, such as real-time assistants or live caption-to-speech conversion.

<CardGroup cols={2}>
  <Card title="Response Format" icon="file" iconColor="purple">
    <code>audio/mpeg</code> (chunked MP3)
  </Card>

  <Card title="First Byte Latency" icon="clock" iconColor="orange">
    \< 500ms
  </Card>
</CardGroup>

## Request Parameters

<ParamField body="input" type="string" required>
  The text to convert to speech. Maximum 5,000 characters.
</ParamField>

<ParamField body="model" type="string" required>
  The synthesis model to use. Currently supported: <code>legacy-v2.5</code>
</ParamField>

<ParamField body="voice" type="string" required>
  The voice ID to use. Get available voices from the{" "}
  <a href="/voices">voices endpoint</a>.
</ParamField>

<ParamField body="pitch" type="string">
  Adjust the voice pitch. Range: <code>-100%</code> to <code>+100%</code>.
  Default: <code>+0%</code>
</ParamField>

<ParamField body="style" type="string">
  Emotional speaking style. Options: <code>neutral</code>, <code>cheerful</code>,{" "}
  <code>calm</code>, <code>angry</code>, <code>sad</code>, <code>excited</code>,{" "}
  <code>whispering</code>. Default: <code>calm</code>
</ParamField>

<ParamField body="styleDegree" type="number">
  Intensity of the selected style. Range: <code>0.5</code> to <code>2.0</code>.
  Default: <code>1.5</code>
</ParamField>

<ParamField body="lang" type="string">
  BCP-47 language code (e.g., <code>en-US</code>, <code>fr-FR</code>). Default:{" "}
  <code>en-US</code>
</ParamField>

## Examples

<Tabs>
  <Tab title="curl">
    ```bash
    curl -X POST https://api.suonora.com/v1/audio/stream \
      -H "Authorization: Bearer YOUR_API_KEY" \
      -H "Content-Type: application/json" \
      --output - \
      -d '{
        "input": "Welcome to Suonora streaming!",
        "model": "legacy-v2.5",
        "voice": "axel",
        "style": "cheerful",
        "styleDegree": 1.2
      }' | ffplay -autoexit -nodisp -
    ```
  </Tab>

  <Tab title="Node.js">
    ```javascript
    const Suonora = require('suonora-sdk');
    const { createWriteStream } = require('fs');
    const { pipeline } = require('stream/promises');

    const suonora = new Suonora({
      apiKey: 'YOUR_API_KEY'
    });

    async function streamSpeech() {
      try {
        const stream = await suonora.audio.stream({
          input: "Welcome to Suonora streaming!",
          model: "legacy-v2.5",
          voice: "axel",
          style: "cheerful",
          styleDegree: 1.2
        });

        // Pipe to file or audio player
        await pipeline(
          stream,
          createWriteStream("output.mp3")
        );
        console.log("Stream completed");
      } catch (error) {
        console.error("Error:", error.message);
      }
    }

    streamSpeech();
    ```
  </Tab>

  <Tab title="Python">
    ```python
    import requests
    import sys

    url = "https://api.suonora.com/v1/audio/stream"
    headers = {
      "Authorization": "Bearer YOUR_API_KEY",
      "Content-Type": "application/json"
    }
    data = {
      "input": "Welcome to Suonora streaming!",
      "model": "legacy-v2.5",
      "voice": "axel",
      "style": "cheerful",
      "styleDegree": 1.2
    }

    try:
      with requests.post(url, json=data, headers=headers, stream=True) as response:
        response.raise_for_status()

        # Stream to file
        with open("output.mp3", "wb") as f:
          for chunk in response.iter_content(chunk_size=8192):
            if chunk:
              f.write(chunk)
              # Optional: Process chunk in real-time
              sys.stdout.buffer.write(chunk)
              sys.stdout.buffer.flush()
    except requests.exceptions.RequestException as e:
      print(f"Error: {e}")
    ```
  </Tab>

  <Tab title="JavaScript (Browser)">
    ```javascript
    async function streamSpeech() {
      try {
        const response = await fetch("https://api.suonora.com/v1/audio/stream", {
          method: "POST",
          headers: {
            "Authorization": "Bearer YOUR_API_KEY",
            "Content-Type": "application/json"
          },
          body: JSON.stringify({
            input: "Welcome to Suonora streaming!",
            model: "legacy-v2.5",
            voice: "axel",
            style: "cheerful",
            styleDegree: 1.2
          })
        });

        if (!response.ok) {
          throw new Error(`HTTP error! status: ${response.status}`);
        }

        // Set up MediaSource for streaming playback
        const mediaSource = new MediaSource();
        const audio = document.getElementById('player');
        audio.src = URL.createObjectURL(mediaSource);

        mediaSource.addEventListener('sourceopen', async () => {
          const sourceBuffer = mediaSource.addSourceBuffer('audio/mpeg');
          const reader = response.body.getReader();

          while (true) {
            const { done, value } = await reader.read();
            if (done) {
              mediaSource.endOfStream();
              break;
            }

            // Append chunk to source buffer
            await new Promise(resolve => {
              sourceBuffer.appendBuffer(value);
              sourceBuffer.addEventListener('updateend', resolve, { once: true });
            });
          }
        });

        // Start playback
        audio.play();
      } catch (error) {
        console.error("Error:", error);
      }
    }
    ```
  </Tab>
</Tabs>

## Response

The endpoint streams MP3 audio data with the following headers:

<ResponseField header="Content-Type">
  <code>audio/mpeg</code>
</ResponseField>

<ResponseField header="Transfer-Encoding">
  <code>chunked</code>
</ResponseField>

## Error Responses

<ResponseCode status={400} title="Invalid Request">
  The request parameters are invalid or missing required fields.
</ResponseCode>

<ResponseCode status={401} title="Unauthorized">
  The API key is invalid or missing.
</ResponseCode>

<ResponseCode status={429} title="Rate Limit Exceeded">
  Too many requests. Implement exponential backoff.
</ResponseCode>

<ResponseCode status={500} title="Server Error">
  An unexpected error occurred. Try again later.
</ResponseCode>

## Best Practices

* **Connection Management**: Use HTTP/2 or keep-alive connections to reduce latency
* **Back-pressure**: Process chunks as they arrive to maintain stream health
* **Error Recovery**: Implement reconnection logic for network interruptions
* **Browser Support**: Use MediaSource API for optimal browser streaming
* **Security**: Keep your API key secure and never expose it in client-side code

## Streaming vs Standard Endpoint

<CardGroup cols={2}>
  <Card title="Use Streaming When" icon="lightning" iconColor="green">
    * Real-time playback is needed - Low latency is critical - Processing long
      texts - Building conversational apps
  </Card>

  <Card title="Use Standard When" icon="download" iconColor="blue">
    * Saving audio to files - Offline caching - Simple playback - Short text
      snippets
  </Card>
</CardGroup>

{" "}
