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

# TTS in five minutes

> Generate your first Rime TTS audio clip in five minutes using cURL, Python, JavaScript, or TypeScript.

This guide shows you how to generate your first audio clip with Rime's text-to-speech (TTS) API and experiment with different voices and speech customizations.

## Prerequisites

To follow this guide, you need:

* **A Rime API token:** Create a free [Rime account](https://app.rime.ai/signup/) and copy your API key from the [API Tokens](https://app.rime.ai/tokens/) page.
* A language runtime, depending on which tab you follow:
  * **cURL** — just a terminal (preinstalled on macOS and Linux).
  * **Python** — [Python 3.10](https://www.python.org/downloads/release/python-3100/) or later.
  * **JavaScript** — [Node.js 18](https://nodejs.org/) or later.
  * **TypeScript** — Node.js 18+ plus [tsx](https://github.com/privatenumber/tsx) (`npm install -g tsx`).

Code blocks in this guide are tabbed. Pick cURL, Python, JavaScript, or TypeScript in each block to follow your preferred language.

## Create your script

If you'd rather paste a working file and read along, grab the full script below. Otherwise, continue step-by-step.

### Full script

Create a file called `rime_hello_world.py`, `rime_hello_world.js`, or `rime_hello_world.ts` (or run the cURL version directly in your terminal) and paste the full script:

<Accordion title="Full script (copy/paste)">
  <CodeGroup>
    ```bash cURL theme={null}
    curl --request POST \
      --url https://users.rime.ai/v1/rime-tts \
      --header 'Authorization: Bearer your_api_key_here' \
      --header 'Content-Type: application/json' \
      --header 'Accept: audio/wav' \
      --output output.wav \
      --data '{
        "text": "Hello! This is Rime speaking.",
        "speaker": "celeste",
        "modelId": "coda"
      }'
    ```

    ```python Python theme={null}
    import json
    import urllib.request

    RIME_API_KEY = "your_api_key_here"

    headers = {
        "Accept": "audio/wav",
        "Authorization": f"Bearer {RIME_API_KEY}",
        "Content-Type": "application/json"
    }

    payload = {
        "text": "Hello! This is Rime speaking.",
        "speaker": "celeste",
        "modelId": "coda"
    }

    data = json.dumps(payload).encode("utf-8")

    request = urllib.request.Request(
        "https://users.rime.ai/v1/rime-tts",
        data=data,
        headers=headers,
        method="POST"
    )

    with urllib.request.urlopen(request) as response:
        with open("output.wav", "wb") as f:
            while chunk := response.read(4096):
                f.write(chunk)

    print("Audio saved to output.wav")
    ```

    ```javascript JavaScript theme={null}
    const fs = require("fs");

    const RIME_API_KEY = "your_api_key_here";

    const headers = {
        "Accept": "audio/wav",
        "Authorization": `Bearer ${RIME_API_KEY}`,
        "Content-Type": "application/json"
    };

    const payload = {
        text: "Hello! This is Rime speaking.",
        speaker: "celeste",
        modelId: "coda"
    };

    async function generateSpeech() {
        const response = await fetch("https://users.rime.ai/v1/rime-tts", {
            method: "POST",
            headers: headers,
            body: JSON.stringify(payload)
        });

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

        const buffer = await response.arrayBuffer();
        fs.writeFileSync("output.wav", Buffer.from(buffer));
        console.log("Audio saved to output.wav");
    }

    generateSpeech();
    ```

    ```typescript TypeScript theme={null}
    import * as fs from "fs";

    const RIME_API_KEY: string = "your_api_key_here";

    const headers: Record<string, string> = {
        "Accept": "audio/wav",
        "Authorization": `Bearer ${RIME_API_KEY}`,
        "Content-Type": "application/json"
    };

    const payload = {
        text: "Hello! This is Rime speaking.",
        speaker: "celeste",
        modelId: "coda"
    };

    async function generateSpeech(): Promise<void> {
        const response = await fetch("https://users.rime.ai/v1/rime-tts", {
            method: "POST",
            headers: headers,
            body: JSON.stringify(payload)
        });

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

        const buffer = await response.arrayBuffer();
        fs.writeFileSync("output.wav", Buffer.from(buffer));
        console.log("Audio saved to output.wav");
    }

    generateSpeech();
    ```
  </CodeGroup>
</Accordion>

### Step-by-step code

Create a file called `rime_hello_world.py`, `rime_hello_world.js`, or `rime_hello_world.ts` and import the required library modules:

<CodeGroup>
  ```python Python theme={null}
  import json
  import urllib.request
  ```

  ```javascript JavaScript theme={null}
  const fs = require("fs");
  ```

  ```typescript TypeScript theme={null}
  import * as fs from "fs";
  ```
</CodeGroup>

Next, we'll create a request to the Rime API.

Set the request headers, specifying the Rime API key that you copied:

<CodeGroup>
  ```python Python theme={null}
  RIME_API_KEY = "your_api_key_here"

  headers = {
      "Accept": "audio/wav",
      "Authorization": f"Bearer {RIME_API_KEY}",
      "Content-Type": "application/json"
  }
  ```

  ```javascript JavaScript theme={null}
  const RIME_API_KEY = "your_api_key_here";

  const headers = {
      "Accept": "audio/wav",
      "Authorization": `Bearer ${RIME_API_KEY}`,
      "Content-Type": "application/json"
  };
  ```

  ```typescript TypeScript theme={null}
  const RIME_API_KEY: string = "your_api_key_here";

  const headers: Record<string, string> = {
      "Accept": "audio/wav",
      "Authorization": `Bearer ${RIME_API_KEY}`,
      "Content-Type": "application/json"
  };
  ```
</CodeGroup>

Configure a payload specifying the details of the request:

<CodeGroup>
  ```python Python theme={null}
  payload = {
      "text": "Hello! This is Rime speaking.",
      "speaker": "celeste",
      "modelId": "coda"
  }
  ```

  ```javascript JavaScript theme={null}
  const payload = {
      text: "Hello! This is Rime speaking.",
      speaker: "celeste",
      modelId: "coda"
  };
  ```

  ```typescript TypeScript theme={null}
  const payload = {
      text: "Hello! This is Rime speaking.",
      speaker: "celeste",
      modelId: "coda"
  };
  ```
</CodeGroup>

This payload includes the three required parameters:

* `text` adds the text that the model converts to speech.
* `speaker` sets the voice that the agent uses (view your options on our [Voices](/docs/voices) page).
* `modelId` specifies which model the agent uses. Use `coda` for our most realistic flagship voices, or `mistv3` for fast synthesis with the classic Mist lineup.

The [Coda API reference](/api-reference/coda/http) details the many optional parameters you can add to request payloads.

Now that you've created the headers and payload, make a `POST` request to the Rime API and write the streamed audio response to a file:

<CodeGroup>
  ```python Python theme={null}
  data = json.dumps(payload).encode("utf-8")

  request = urllib.request.Request(
      "https://users.rime.ai/v1/rime-tts",
      data=data,
      headers=headers,
      method="POST"
  )

  with urllib.request.urlopen(request) as response:
      with open("output.wav", "wb") as f:
          while chunk := response.read(4096):
              f.write(chunk)

  print("Audio saved to output.wav")
  ```

  ```javascript JavaScript theme={null}
  async function generateSpeech() {
      const response = await fetch("https://users.rime.ai/v1/rime-tts", {
          method: "POST",
          headers: headers,
          body: JSON.stringify(payload)
      });

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

      const buffer = await response.arrayBuffer();
      fs.writeFileSync("output.wav", Buffer.from(buffer));
      console.log("Audio saved to output.wav");
  }

  generateSpeech();
  ```

  ```typescript TypeScript theme={null}
  async function generateSpeech(): Promise<void> {
      const response = await fetch("https://users.rime.ai/v1/rime-tts", {
          method: "POST",
          headers: headers,
          body: JSON.stringify(payload)
      });

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

      const buffer = await response.arrayBuffer();
      fs.writeFileSync("output.wav", Buffer.from(buffer));
      console.log("Audio saved to output.wav");
  }

  generateSpeech();
  ```
</CodeGroup>

Streaming allows audio playback to begin before generation completes. This enables conversational flow, as the user can start listening to responses before the entire audio clip has been generated.

Although streaming is less important in this example, because we're writing to a file, it's vital when using models in real-time conversations. If this sounds interesting, follow the [LiveKit quickstart](/docs/quickstart-livekit) to create your first conversational agent.

## Test the script

Run your script from the terminal:

<CodeGroup>
  ```bash Python theme={null}
  python rime_hello_world.py
  ```

  ```bash JavaScript theme={null}
  node rime_hello_world.js
  ```

  ```bash TypeScript theme={null}
  npx tsx rime_hello_world.ts
  ```
</CodeGroup>

On a successful run, the terminal displays a confirmation that your audio file has been saved:

```bash theme={null}
'Audio saved to output.wav'
```

## Choose a voice

Rime offers a range of voices with different personalities. To change the voice, update the `speaker` parameter in your request:

<CodeGroup>
  ```python Python theme={null}
  payload = {
      "text": "Hello! This is Rime speaking.",
      "speaker": "orion",  # Try different voices here
      "modelId": "coda"
  }
  ```

  ```javascript JavaScript theme={null}
  const payload = {
      text: "Hello! This is Rime speaking.",
      speaker: "orion",  // Try different voices here
      modelId: "coda"
  };
  ```

  ```typescript TypeScript theme={null}
  const payload = {
      text: "Hello! This is Rime speaking.",
      speaker: "orion",  // Try different voices here
      modelId: "coda"
  };
  ```
</CodeGroup>

Browse all available voices on the [Voices](/docs/voices) page.

## Custom pronunciation

<Note>Custom pronunciation is supported on **Mist v1 and v2** only. Coda, Arcana, and Mist v3 do not support [`phonemizeBetweenBrackets`](/docs/custom-pronunciation) yet.</Note>

The `mistv2` model lets you specify the pronunciation of brand names or uncommon words using Rime's [phonetic alphabet](/docs/custom-pronunciation). Add the custom pronunciation in curly brackets and set [`phonemizeBetweenBrackets`](/docs/custom-pronunciation) to `true`:

<CodeGroup>
  ```python Python theme={null}
  payload = {
      "text": "Welcome to {r1Ym} labs.",
      "speaker": "peak",
      "modelId": "mistv2",
      "phonemizeBetweenBrackets": True
  }
  ```

  ```javascript JavaScript theme={null}
  const payload = {
      text: "Welcome to {r1Ym} labs.",
      speaker: "peak",
      modelId: "mistv2",
      phonemizeBetweenBrackets: true
  };
  ```

  ```typescript TypeScript theme={null}
  const payload = {
      text: "Welcome to {r1Ym} labs.",
      speaker: "peak",
      modelId: "mistv2",
      phonemizeBetweenBrackets: true
  };
  ```
</CodeGroup>

Use the [Pronunciation tool](https://app.rime.ai//pronunciation) on the dashboard to generate phonetic strings for any word.

## Next steps

Now that you can generate TTS audio, try following the [LiveKit quickstart guide](/docs/quickstart-livekit) to learn how you can set up a real-time conversation with an agent.

Check out these resources to get more familiar with Rime:

<CardGroup cols={2}>
  <Card title="Models" icon="microchip" href="/docs/models">
    Compare Coda (flagship) and Mist v3 (fast)
  </Card>

  <Card title="Voices" icon="waveform" href="/docs/voices">
    Browse all available voice options
  </Card>

  <Card title="Latency" icon="gauge-high" href="/docs/latency">
    Optimize for real-time performance
  </Card>

  <Card title="Coda Streaming API" icon="bolt" href="/api-reference/coda/http">
    Stream audio with our flagship model
  </Card>
</CardGroup>
