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

# TTS API Quickstart

> Learn how to use PlayAI's Text-to-Speech API for natural conversations

This guide provides a step-by-step approach to using the PlayAI's Text-to-Speech API to convert text into natural human-like sounding audio.

In this example, we'll have [Dialog 1.0](/documentation/text-to-speech/tts-models#dialog-10) create a simple audio from the given input text.

## Prerequisites

* Access your [credentials](https://play.ai/api/keys) (API key and user ID)
* Development environment for your chosen programming language

## Steps

<Steps>
  <Step title="Set Up Environment Variables">
    Add your API key and user ID to your environment variables.

    <CodeGroup>
      ```bash macOS (zsh) theme={null}
      echo 'export PLAYAI_API_KEY="your_api_key_here"' >> ~/.zshrc
      echo 'export PLAYAI_USER_ID="your_user_id_here"' >> ~/.zshrc
      source ~/.zshrc
      ```

      ```bash bash theme={null}
      echo 'export PLAYAI_API_KEY="your_api_key_here"' >> ~/.bashrc
      echo 'export PLAYAI_USER_ID="your_user_id_here"' >> ~/.bashrc
      source ~/.bashrc
      ```

      ```cmd Windows theme={null}
      setx PLAYAI_API_KEY "your_api_key_here"
      setx PLAYAI_USER_ID "your_user_id_here"
      ```
    </CodeGroup>
  </Step>

  <Step title="Configure API Access">
    Create a script with the following authentication setup for your chosen language:

    <CodeGroup>
      ```python Python theme={null}
      import os

      api_key = os.getenv("PLAYAI_API_KEY")
      user_id = os.getenv("PLAYAI_USER_ID")

      headers = {
          'Authorization': f'Bearer {api_key}',
          'Content-Type': 'application/json',
          'X-USER-ID': user_id
      }
      ```

      ```javascript JavaScript theme={null}
      const apiKey = process.env.PLAYAI_API_KEY;
      const userId = process.env.PLAYAI_USER_ID;

      const headers = {
        'Authorization': `Bearer ${apiKey}`,
        'Content-Type': 'application/json',
        'X-USER-ID': userId
      };
      ```

      ```go Go theme={null}
      apiKey := os.Getenv("PLAYAI_API_KEY")
      userId := os.Getenv("PLAYAI_USER_ID")

      headers := map[string]string{
        "Authorization": fmt.Sprintf("Bearer %s", apiKey),
        "Content-Type": "application/json",
        "X-USER-ID": userId,
      }
      ```

      ```dart Dart theme={null}
      final apiKey = Platform.environment['PLAYAI_API_KEY'];
      final userId = Platform.environment['PLAYAI_USER_ID'];

      final headers = {
        'Authorization': 'Bearer $apiKey',
        'Content-Type': 'application/json',
        'X-USER-ID': userId,
      };
      ```

      ```swift Swift theme={null}
      let apiKey = ProcessInfo.processInfo.environment["PLAYAI_API_KEY"] ?? ""
      let userId = ProcessInfo.processInfo.environment["PLAYAI_USER_ID"] ?? ""

      let headers = [
        "Authorization": "Bearer \(apiKey)",
        "Content-Type": "application/json",
        "X-USER-ID": userId
      ]
      ```
    </CodeGroup>
  </Step>

  <Step title="Prepare API Parameters">
    Define your API payload with these key parameters:

    * **`model`**: Use `PlayDialog` for multi-turn conversation
      generation
    * **`text`**: Your input text for speech generation
    * **`voice`**: URL path to the voice manifest
    * **`output_format`**: Choose `wav` or `mp3`

    <CodeGroup>
      ```python Python theme={null}
      json_data = {
          'model': 'PlayDialog',
          'text': "All human wisdom is summed up in these two words: Wait and hope.",
          'voice': 's3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json',
          'outputFormat': 'wav'
      }
      ```

      ```javascript JavaScript theme={null}
      const jsonData = {
        model: 'PlayDialog',
        text: "All human wisdom is summed up in these two words: Wait and hope.",
        voice: 's3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json',
        outputFormat: 'wav'
      };
      ```

      ```go Go theme={null}
      jsonData := map[string]interface{}{
        "model": "PlayDialog",
        "text": "All human wisdom is summed up in these two words: Wait and hope.",
        "voice": "s3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json",
        "outputFormat": "wav",
      }
      ```

      ```dart Dart theme={null}
      final jsonData = {
        'model': 'PlayDialog',
        'text': 'All human wisdom is summed up in these two words: Wait and hope.',
        'voice': 's3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json',
        'outputFormat': 'wav',
      };
      ```

      ```swift Swift theme={null}
      let jsonData: [String: Any] = [
        "model": "PlayDialog",
        "text": "All human wisdom is summed up in these two words: Wait and hope.",
        "voice": "s3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json",
        "outputFormat": "wav"
      ]
      ```
    </CodeGroup>
  </Step>

  <Step title="Implement API Call">
    Create the complete API implementation in your chosen language:

    <CodeGroup>
      ```python Python theme={null}
      response = requests.post('https://api.play.ai/api/v1/tts/stream',
                             headers=headers,
                             json=json_data)

      if response.status_code == 200:
          with open('dialogue.wav', 'wb') as f:
              f.write(response.content)
          print("Audio file saved as dialogue.wav")
      else:
          print(f"Request failed with status code {response.status_code}: {response.text}")
      ```

      ```javascript JavaScript theme={null}
      fetch('https://api.play.ai/api/v1/tts/stream', {
        method: 'POST',
        headers: headers,
        body: JSON.stringify(jsonData)
      })
      .then(response => {
        if (response.ok) {
          return response.blob();
        }
        throw new Error(`Request failed with status ${response.status}`);
      })
      .then(blob => {
        const url = window.URL.createObjectURL(blob);
        const a = document.createElement('a');
        a.href = url;
        a.download = 'dialogue.wav';
        a.click();
        window.URL.revokeObjectURL(url);
        console.log("Audio file saved as dialogue.wav");
      })
      .catch(error => console.error('Error:', error));
      ```

      ```go Go theme={null}
      jsonBytes, _ := json.Marshal(jsonData)
      req, _ := http.NewRequest("POST", "https://api.play.ai/api/v1/tts/stream", bytes.NewBuffer(jsonBytes))

      for key, value := range headers {
        req.Header.Add(key, value)
      }

      client := &http.Client{}
      resp, err := client.Do(req)
      if err != nil {
        log.Fatal(err)
      }
      defer resp.Body.Close()

      if resp.StatusCode == 200 {
        out, _ := os.Create("dialogue.wav")
        defer out.Close()
        io.Copy(out, resp.Body)
        fmt.Println("Audio file saved as dialogue.wav")
      } else {
        body, _ := io.ReadAll(resp.Body)
        fmt.Printf("Request failed with status code %d: %s\n", resp.StatusCode, string(body))
      }
      ```

      ```dart Dart theme={null}
      final response = await http.post(
        Uri.parse('https://api.play.ai/api/v1/tts/stream'),
        headers: headers,
        body: jsonEncode(jsonData),
      );

      if (response.statusCode == 200) {
        final file = File('dialogue.wav');
        await file.writeAsBytes(response.bodyBytes);
        print('Audio file saved as dialogue.wav');
      } else {
        print('Request failed with status code ${response.statusCode}: ${response.body}');
      }
      ```

      ```swift Swift theme={null}
      guard let jsonData = try? JSONSerialization.data(withJSONObject: jsonData) else {
        print("Failed to serialize JSON data")
        exit(1)
      }

      var request = URLRequest(url: URL(string: "https://api.play.ai/api/v1/tts/stream")!)
      request.httpMethod = "POST"
      request.allHTTPHeaderFields = headers
      request.httpBody = jsonData

      let task = URLSession.shared.dataTask(with: request) { data, response, error in
        if let error = error {
            print("Error: \(error)")
            return
        }

        guard let httpResponse = response as? HTTPURLResponse else {
            print("Invalid response")
            return
        }

        if httpResponse.statusCode == 200 {
            if let data = data {
                do {
                    try data.write(to: URL(fileURLWithPath: "dialogue.wav"))
                    print("Audio file saved as dialogue.wav")
                } catch {
                    print("Error saving file: \(error)")
                }
            }
        } else {
            print("Request failed with status code \(httpResponse.statusCode)")
            if let data = data, let responseString = String(data: data, encoding: .utf8) {
                print("Response: \(responseString)")
            }
        }
      }
      task.resume()
      ```
    </CodeGroup>
  </Step>

  <Step title="Run and Test">
    Follow these steps to run your code:

    <Tabs>
      <Tab title="Python">
        1. Save your code as `playdialog_tts.py`
        2. Open terminal in your code directory
        3. Run: `python3 playdialog_tts.py`
        4. Check for the generated `dialogue.wav` file
      </Tab>

      <Tab title="JavaScript">
        1. Save your code as `playdialog_tts.js`
        2. Install dependencies: `npm install node-fetch`
        3. Run: `node playdialog_tts.js`
        4. Check for the generated `dialogue.wav` file
      </Tab>

      <Tab title="Go">
        1. Save your code as `playdialog_tts.go`
        2. Run: `go run playdialog_tts.go`
        3. Check for the generated `dialogue.wav` file
      </Tab>

      <Tab title="Dart">
        1. Save your code as `playdialog_tts.dart`
        2. Install dependencies: `dart pub add http`
        3. Run: `dart run playdialog_tts.dart`
        4. Check for the generated `dialogue.wav` file
      </Tab>

      <Tab title="Swift">
        1. Save your code as `playdialog_tts.swift`
        2. Run: `swift playdialog_tts.swift`
        3. Check for the generated `dialogue.wav` file
      </Tab>
    </Tabs>
  </Step>

  <Step title="Customize and Adapt">
    Modify your implementation by:

    * Updating the input text
    * Changing speaker details and voices
    * Adjusting output format as needed
    * Adding multiple speakers or complex dialogues
  </Step>
</Steps>

## Complete Code

<CodeGroup>
  ```python Python [expandable] theme={null}
  import os
  import requests

  api_key = os.getenv("PLAYAI_API_KEY")
  user_id = os.getenv("PLAYAI_USER_ID")

  headers = {
      'Authorization': f'Bearer {api_key}',
      'Content-Type': 'application/json',
      'X-USER-ID': user_id
  }

  json_data = {
      'model': 'PlayDialog',
      'text': "All human wisdom is summed up in these two words: Wait and hope.",
      'voice': 's3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json',
      'outputFormat': 'wav'
  }

  response = requests.post('https://api.play.ai/api/v1/tts/stream',
                         headers=headers,
                         json=json_data)

  if response.status_code == 200:
      with open('dialogue.wav', 'wb') as f:
          f.write(response.content)
      print("Audio file saved as dialogue.wav")
  else:
      print(f"Request failed with status code {response.status_code}: {response.text}")
  ```

  ```javascript JavaScript [expandable] theme={null}
  const fetch = require('node-fetch');

  const apiKey = process.env.PLAYAI_API_KEY;
  const userId = process.env.PLAYAI_USER_ID;

  const headers = {
    'Authorization': `Bearer ${apiKey}`,
    'Content-Type': 'application/json',
    'X-USER-ID': userId
  };

  const jsonData = {
    model: 'PlayDialog',
    text: "All human wisdom is summed up in these two words: Wait and hope.",
    voice: 's3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json',
    outputFormat: 'wav'
  };

  fetch('https://api.play.ai/api/v1/tts/stream', {
    method: 'POST',
    headers: headers,
    body: JSON.stringify(jsonData)
  })
  .then(response => {
    if (response.ok) {
      return response.blob();
    }
    throw new Error(`Request failed with status ${response.status}`);
  })
  .then(blob => {
    const url = window.URL.createObjectURL(blob);
    const a = document.createElement('a');
    a.href = url;
    a.download = 'dialogue.wav';
    a.click();
    window.URL.revokeObjectURL(url);
    console.log("Audio file saved as dialogue.wav");
  })
  .catch(error => console.error('Error:', error));
  ```

  ```go Go [expandable] theme={null}
  package main

  import (
    "bytes"
    "encoding/json"
    "fmt"
    "io"
    "log"
    "net/http"
    "os"
  )

  func main() {
    apiKey := os.Getenv("PLAYAI_API_KEY")
    userId := os.Getenv("PLAYAI_USER_ID")

    headers := map[string]string{
      "Authorization": fmt.Sprintf("Bearer %s", apiKey),
      "Content-Type": "application/json",
      "X-USER-ID": userId,
    }

    jsonData := map[string]interface{}{
      "model": "PlayDialog",
      "text": "All human wisdom is summed up in these two words: Wait and hope.",
      "voice": "s3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json",
      "outputFormat": "wav",
    }

    jsonBytes, _ := json.Marshal(jsonData)
    req, _ := http.NewRequest("POST", "https://api.play.ai/api/v1/tts/stream", bytes.NewBuffer(jsonBytes))
    
    for key, value := range headers {
      req.Header.Add(key, value)
    }

    client := &http.Client{}
    resp, err := client.Do(req)
    if err != nil {
      log.Fatal(err)
    }
    defer resp.Body.Close()

    if resp.StatusCode == 200 {
      out, _ := os.Create("dialogue.wav")
      defer out.Close()
      io.Copy(out, resp.Body)
      fmt.Println("Audio file saved as dialogue.wav")
    } else {
      body, _ := io.ReadAll(resp.Body)
      fmt.Printf("Request failed with status code %d: %s\n", resp.StatusCode, string(body))
    }
  }
  ```

  ```dart Dart [expandable] theme={null}
  import 'dart:io';
  import 'package:http/http.dart' as http;
  import 'dart:convert';

  void main() async {
    final apiKey = Platform.environment['PLAYAI_API_KEY'];
    final userId = Platform.environment['PLAYAI_USER_ID'];

    final headers = {
      'Authorization': 'Bearer $apiKey',
      'Content-Type': 'application/json',
      'X-USER-ID': userId,
    };

    final jsonData = {
      'model': 'PlayDialog',
      'text': 'All human wisdom is summed up in these two words: Wait and hope.',
      'voice': 's3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json',
      'outputFormat': 'wav',
    };

    final response = await http.post(
      Uri.parse('https://api.play.ai/api/v1/tts/stream'),
      headers: headers,
      body: jsonEncode(jsonData),
    );

    if (response.statusCode == 200) {
      final file = File('dialogue.wav');
      await file.writeAsBytes(response.bodyBytes);
      print('Audio file saved as dialogue.wav');
    } else {
      print('Request failed with status code ${response.statusCode}: ${response.body}');
    }
  }
  ```

  ```swift Swift [expandable] theme={null}
  import Foundation

  let apiKey = ProcessInfo.processInfo.environment["PLAYAI_API_KEY"] ?? ""
  let userId = ProcessInfo.processInfo.environment["PLAYAI_USER_ID"] ?? ""

  let headers = [
    "Authorization": "Bearer \(apiKey)",
    "Content-Type": "application/json",
    "X-USER-ID": userId
  ]

  let jsonData: [String: Any] = [
    "model": "PlayDialog",
    "text": "All human wisdom is summed up in these two words: Wait and hope.",
    "voice": "s3://voice-cloning-zero-shot/baf1ef41-36b6-428c-9bdf-50ba54682bd8/original/manifest.json",
    "outputFormat": "wav"
  ]

  guard let jsonData = try? JSONSerialization.data(withJSONObject: jsonData) else {
    print("Failed to serialize JSON data")
    exit(1)
  }

  var request = URLRequest(url: URL(string: "https://api.play.ai/api/v1/tts/stream")!)
  request.httpMethod = "POST"
  request.allHTTPHeaderFields = headers
  request.httpBody = jsonData

  let task = URLSession.shared.dataTask(with: request) { data, response, error in
    if let error = error {
        print("Error: \(error)")
        return
    }

    guard let httpResponse = response as? HTTPURLResponse else {
        print("Invalid response")
        return
    }

    if httpResponse.statusCode == 200 {
        if let data = data {
            do {
                try data.write(to: URL(fileURLWithPath: "dialogue.wav"))
                print("Audio file saved as dialogue.wav")
            } catch {
                print("Error saving file: \(error)")
            }
        }
    } else {
        print("Request failed with status code \(httpResponse.statusCode)")
        if let data = data, let responseString = String(data: data, encoding: .utf8) {
            print("Response: \(responseString)")
        }
    }
  }
  task.resume()
  ```
</CodeGroup>

## Troubleshooting

If you encounter issues, check these common problems:

* **Authentication Issues:**
  * Verify your API key and user ID
  * Confirm the `AUTHORIZATION` header includes "Bearer " prefix

* **API Endpoint Errors:**
  * Verify the correct PlayAI's Dialog 1.0 API endpoint URL
  * Confirm the `model` name is `PlayDialog`

* **Language-Specific Issues:**
  * JavaScript: Ensure `node-fetch` is installed for Node.js environments
  * Go: Check for proper error handling and response body closing
  * Dart: Verify the `http` package is added to your `pubspec.yaml`
  * Swift: Make sure you're running on macOS for file system access
