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

# Speak

> Convert text to speech

<Note>
  This endpoint only supports Bland's Beige Voices.
</Note>

<Note>
  All generations are automatically stored and can be retrieved later via [List TTS Generations](/api-v1/get/speak-samples) and [Get TTS Generation](/api-v1/get/speak-samples-id).
</Note>

## Pricing

Text-to-speech pricing varies by plan:

* **Start Plan**: \$0.02 per 100 characters (Default)
* **Build Plan**: \$0.02 per 150 characters
* **Scale Plan**: \$0.02 per 200 characters
* **Enterprise Plan**: \$0.02 per 400 characters

***

## Headers

<ParamField header="authorization" type="string" required>
  Your API key for authentication.
</ParamField>

***

## Body Parameters

<ParamField body="voice" type="string" required>
  The ID or name of the Beige Voice to use for speech synthesis.
</ParamField>

<ParamField body="text" type="string" required>
  The text content to be converted to speech.
</ParamField>

<ParamField body="output_format" type="string" default="pcm_44100">
  The audio output format for the generated speech.

  **Available formats:**

  * `pcm_8000` - PCM 8kHz, 16-bit, mono
  * `pcm_16000` - PCM 16kHz, 16-bit, mono
  * `pcm_24000` - PCM 24kHz, 16-bit, mono
  * `pcm_44100` - PCM 44.1kHz, 16-bit, mono (default)
  * `ulaw_8000` - μ-law 8kHz, 8-bit, mono
</ParamField>

<ParamField body="consistency" type="float">
  Controls voice consistency and stability. Value between 0 and 1.

  * `0` - More varied, expressive speech
  * `1` - More consistent, stable speech
</ParamField>

<ParamField body="expressiveness" type="float">
  Controls voice expressiveness and emotion. Value between 0 and 1.

  * `0` - More monotone, neutral speech
  * `1` - More expressive, emotional speech
</ParamField>

<ParamField body="stream" type="boolean" default="false">
  Enable streaming audio response for real-time playback.

  When `true`, audio is streamed as it's generated. When `false`, the complete audio file is returned after generation.
</ParamField>

***

## Response

### Non-Streaming Response

<ResponseField type="audio/x-wav" name="audio">
  Complete WAV audio file with the specified output format containing the synthesized speech.
</ResponseField>

### Streaming Response

<ResponseField type="audio/x-wav" name="audio_stream">
  Chunked WAV audio stream. The response starts with a WAV header followed by audio data chunks as they're generated.
</ResponseField>

### Response Headers

<ResponseField name="x-latency" type="string">
  Time in milliseconds from request to first audio chunk/complete response.
</ResponseField>

<ResponseField name="x-cost" type="string">
  Cost in USD for the text-to-speech conversion
</ResponseField>

<ResponseField name="Content-Type" type="string">
  Always `audio/x-wav` for successful responses.
</ResponseField>

<ResponseField name="Content-Length" type="string">
  Size of the complete audio file in bytes (non-streaming only).
</ResponseField>

<ResponseField name="Transfer-Encoding" type="string">
  Set to `chunked` for streaming responses.
</ResponseField>

***

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.bland.ai/v1/speak" \
    -H "authorization: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "voice": "Maeve",
      "text": "Hello, this is a test of the text-to-speech system.",
      "output_format": "pcm_44100"
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.bland.ai/v1/speak', {
    method: 'POST',
    headers: {
      'authorization': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      voice: 'Maeve',
      text: 'Hello, this is a test of the text-to-speech system.',
      output_format: 'pcm_44100'
    })
  });

  const audioBuffer = await response.arrayBuffer();
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.bland.ai/v1/speak',
      headers={
          'authorization': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'voice': 'Maeve',
          'text': 'Hello, this is a test of the text-to-speech system.',
          'output_format': 'pcm_44100'
      }
  )

  audio_data = response.content
  ```
</RequestExample>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.bland.ai/v1/speak" \
    -H "authorization: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "voice": "Maeve",
      "text": "This is a streaming example that will return audio chunks as they are generated.",
      "output_format": "pcm_24000",
      "stream": true
    }' \
    --output audio_stream.wav
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.bland.ai/v1/speak', {
    method: 'POST',
    headers: {
      'authorization': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      voice: 'Maeve',
      text: 'This is a streaming example that will return audio chunks as they are generated.',
      output_format: 'pcm_24000',
      stream: true
    })
  });

  const reader = response.body.getReader();
  while (true) {
    const { done, value } = await reader.read();
    if (done) break;
    // Process audio chunk
    console.log('Received chunk:', value);
  }
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.bland.ai/v1/speak',
      headers={
          'authorization': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'voice': 'Maeve',
          'text': 'This is a streaming example that will return audio chunks as they are generated.',
          'output_format': 'pcm_24000',
          'stream': True
      },
      stream=True
  )

  with open('audio_stream.wav', 'wb') as f:
      for chunk in response.iter_content(chunk_size=8192):
          f.write(chunk)
  ```
</RequestExample>

<RequestExample>
  ```bash cURL theme={null}
  curl -X POST "https://api.bland.ai/v1/speak" \
    -H "authorization: YOUR_API_KEY" \
    -H "Content-Type: application/json" \
    -d '{
      "voice": "Maeve",
      "text": "This example uses custom voice parameters for more expressive speech.",
      "output_format": "pcm_16000",
      "consistency": 0.3,
      "expressiveness": 0.8
    }'
  ```

  ```javascript JavaScript theme={null}
  const response = await fetch('https://api.bland.ai/v1/speak', {
    method: 'POST',
    headers: {
      'authorization': 'YOUR_API_KEY',
      'Content-Type': 'application/json'
    },
    body: JSON.stringify({
      voice: 'Maeve',
      text: 'This example uses custom voice parameters for more expressive speech.',
      output_format: 'pcm_16000',
      consistency: 0.3,
      expressiveness: 0.8
    })
  });
  ```

  ```python Python theme={null}
  import requests

  response = requests.post(
      'https://api.bland.ai/v1/speak',
      headers={
          'authorization': 'YOUR_API_KEY',
          'Content-Type': 'application/json'
      },
      json={
          'voice': 'Maeve',
          'text': 'This example uses custom voice parameters for more expressive speech.',
          'output_format': 'pcm_16000',
          'consistency': 0.3,
          'expressiveness': 0.8
      }
  )
  ```
</RequestExample>

<ResponseExample>
  ```json 400 - Missing Text theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Invalid Input",
        "message": "Missing text in request body - must be a string"
      }
    ]
  }
  ```

  ```json 400 - Missing Voice Parameter theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Invalid Input",
        "message": "Missing voice parameter"
      }
    ]
  }
  ```

  ```json 400 - Invalid Output Format theme={null}
  {
    "status": "error", 
    "errors": [
      {
        "error": "Invalid Input",
        "message": "Invalid output_format. Must be one of: pcm_8000, pcm_16000, pcm_24000, pcm_44100, ulaw_8000"
      }
    ]
  }
  ```

  ```json 400 - Invalid Consistency theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Invalid Input",
        "message": "Consistency must be between 0 and 1"
      }
    ]
  }
  ```

  ```json 400 - Invalid Expressiveness theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Invalid Input",
        "message": "Expressiveness must be between 0 and 1"
      }
    ]
  }
  ```

  ```json 400 - Text Too Long theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Invalid Input",
        "message": "Text is too long"
      }
    ]
  }
  ```

  ```json 400 - Service Not Supported theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Service Not Supported", 
        "message": "This endpoint only supports Bland's Beige Voices"
      }
    ]
  }
  ```

  ```json 429 - Rate Limit Exceeded theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Rate Limit Exceeded",
        "message": "Too many requests from this user, please try again later."
      }
    ]
  }
  ```

  ```json 500 - Validation Error theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Validation Error",
        "message": "Specific validation error message"
      }
    ]
  }
  ```

  ```json 500 - Streaming Error theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Streaming Error",
        "message": "An error occurred while streaming the audio. Please try again later."
      }
    ]
  }
  ```

  ```json 500 - Internal Server Error theme={null}
  {
    "status": "error",
    "errors": [
      {
        "error": "Internal Server Error",
        "message": "An unexpected error occurred"
      }
    ]
  }
  ```
</ResponseExample>

***

Docs for agents: [llms.txt](/llms.txt)
