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

# Google Cloud TTS

> Use the Google Cloud Text-to-Speech plugin in a Zero Runtime pipeline. Setup, options, and usage in Python and JavaScript.

Google Cloud Text-to-Speech is a **text-to-speech** plugin. It synthesizes the LLM's reply
into the agent's voice. It occupies the pipeline's `tts` slot.

## Setup

Cloud TTS authenticates with either a service account or an API key. Create one in the
[Google Cloud console](https://console.cloud.google.com/apis/credentials) and export it in
the worker environment:

<CodeGroup>
  ```bash API key theme={null}
  export GOOGLE_API_KEY=<key>
  ```

  ```bash Service account theme={null}
  export GOOGLE_APPLICATION_CREDENTIALS=/path/to/service-account.json
  ```
</CodeGroup>

<Warning>
  Streaming synthesis needs a service account. Cloud TTS refuses an API key on
  `StreamingSynthesize`, and `streaming` defaults to `True` — so an API key alone works only
  with `streaming=False`. The plugin also prefers `GOOGLE_API_KEY` whenever it is set: leave it
  unset when you mean to authenticate with the service account.
</Warning>

### Credential resolution

The plugin chooses one credential when it is constructed, and takes the first that is present:

1. `GOOGLE_API_KEY` when it is unset it will use `GOOGLE_APPLICATION_CREDENTIALS`.
2. `GOOGLE_APPLICATION_CREDENTIALS`, when it points at a readable file — used as
   service-account credentials.

<Warning>
  The fallback is on **absence**, not on failure. Step 2 is reached only when no API key is set
  at all — so if `GOOGLE_API_KEY` is present and Google rejects it, the plugin does not then try
  the service-account file, even when both are configured. Unset `GOOGLE_API_KEY` to make the
  service account the credential in use.
</Warning>

## Usage

Import the plugin and pass it to the pipeline's `tts` slot.

<CodeGroup>
  ```python Python theme={null}
  from zeroruntime.plugins import GoogleTTS

  tts = GoogleTTS(
      voice_config={"name": "en-US-Chirp3-HD-Charon", "languageCode": "en-US"},
      speed=1.0,
  )

  # Pipeline(tts=tts, ...)
  ```

  ```typescript Node JS theme={null}
  import { GoogleTTS } from '@zeroruntime/js-sdk/plugins';

  const tts = GoogleTTS({
    voice_config: {name: 'en-US-Chirp3-HD-Charon', languageCode: 'en-US'},
    speed: 1.0,
  });

  // Pipeline({ tts, ... })
  ```
</CodeGroup>

Everything about the voice lives in `voice_config` — there is no separate `voice` or
`language_code` argument. Omit it entirely and the plugin uses
`en-US-Chirp3-HD-Charon` / `en-US` / `MALE`.

| Key            | Type  | Default                    | Description                                                                                                                                    |
| -------------- | ----- | -------------------------- | ---------------------------------------------------------------------------------------------------------------------------------------------- |
| `name`         | `str` | `"en-US-Chirp3-HD-Charon"` | Cloud TTS voice name, or a bare Gemini voice (e.g. `"Kore"`) when `model` is set.                                                              |
| `languageCode` | `str` | `"en-US"`                  | BCP-47 language code for the voice.                                                                                                            |
| `ssmlGender`   | `str` | `"MALE"`                   | `"MALE"`, `"FEMALE"`, or `"NEUTRAL"`. Sent only for non-Studio Cloud TTS voices — it is omitted for Studio voices and whenever `model` is set. |

## Streaming

`streaming=True` (the default) synthesizes over gRPC `StreamingSynthesize`, which starts
returning audio while the LLM is still producing text. Without a Gemini-TTS `model`, that path
only accepts **Chirp 3 HD** voices; any other voice raises `ValueError` from the constructor.

For a Neural2, Studio, WaveNet, or Standard voice, turn streaming off and the plugin falls back
to per-segment `SynthesizeSpeech` requests:

<CodeGroup>
  ```python Python theme={null}
  from zeroruntime.plugins import GoogleTTS

  tts = GoogleTTS(
      voice_config={"name": "en-US-Neural2-F", "languageCode": "en-US"},
      streaming=False,
  )
  ```

  ```typescript Node JS theme={null}
  import { GoogleTTS } from '@zeroruntime/js-sdk/plugins';

  const tts = GoogleTTS({
    voice_config: {name: 'en-US-Neural2-F', languageCode: 'en-US'},
    streaming: false,
  });
  ```
</CodeGroup>

<Note>
  `pitch` is only sent on the non-streaming path — Cloud TTS's streaming audio config carries
  `speaking_rate` but has no pitch field, so `pitch` is silently inert when `streaming=True`.
</Note>

`streaming=True` and `vertexai=True` cannot be combined; the constructor raises `ValueError`.

## Gemini-TTS

Set `model` to a Gemini-TTS engine to synthesize with Gemini instead of standard Cloud TTS.
The voice name becomes a bare Gemini voice, and `prompt` takes a natural-language style
instruction:

<CodeGroup>
  ```python Python theme={null}
  from zeroruntime.plugins import GoogleTTS

  tts = GoogleTTS(
      model="gemini-3.1-flash-tts-preview",
      voice_config={"name": "Kore", "languageCode": "en-US"},
      prompt="Speak in a warm, professional tone",
  )
  ```

  ```typescript Node JS theme={null}
  import { GoogleTTS } from '@zeroruntime/js-sdk/plugins';

  const tts = GoogleTTS({
    model: 'gemini-3.1-flash-tts-preview',
    voice_config: {name: 'Kore', languageCode: 'en-US'},
    prompt: 'Speak in a warm, professional tone',
  });
  ```
</CodeGroup>

Known engines are `"gemini-3.1-flash-tts-preview"`, `"gemini-2.5-flash-tts"`,
`"gemini-2.5-flash-lite-preview-tts"`, and `"gemini-2.5-pro-tts"`. A Gemini model lifts the
Chirp 3 HD restriction on streaming, and `prompt` is only valid alongside one — passing
`prompt` without `model` raises `ValueError`.

## Vertex AI

`vertexai=True` routes synthesis through the regional Vertex AI endpoint
(`{location}-texttospeech.googleapis.com`) using Application Default Credentials rather than an
API key. It requires `streaming=False`.

<CodeGroup>
  ```python Python theme={null}
  from zeroruntime.plugins import GoogleTTS

  tts = GoogleTTS(
      vertexai=True,
      vertexai_config={"project_id": "my-project", "location": "us-central1"},
      streaming=False,
  )
  ```

  ```typescript Node JS theme={null}
  import { GoogleTTS } from '@zeroruntime/js-sdk/plugins';

  const tts = GoogleTTS({
    vertexai: true,
    vertexai_config: {project_id: 'my-project', location: 'us-central1'},
    streaming: false,
  });
  ```
</CodeGroup>

| Key          | Type          | Default         | Description                                                                                                                                                                                               |
| ------------ | ------------- | --------------- | --------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------- |
| `project_id` | `str \| None` | `None`          | GCP project. Falls back to `GOOGLE_CLOUD_PROJECT`, then `GCLOUD_PROJECT`, then the `project_id` inside the `GOOGLE_APPLICATION_CREDENTIALS` service-account file. `ValueError` when none of them resolve. |
| `location`   | `str`         | `"us-central1"` | Vertex AI region, which also determines the endpoint host. `GOOGLE_CLOUD_LOCATION` is consulted only if this is explicitly emptied — the default is already a value.                                      |

## Custom pronunciations

`custom_pronunciations` overrides how specific phrases are read. The short form is a mapping of
phrase to IPA:

```python theme={null}
tts = GoogleTTS(custom_pronunciations={"tomato": "təˈmeɪtoʊ"})
```

The long form is a list, and lets each entry pick its phonetic encoding — `"ipa"` (default) or
`"x-sampa"`. An unrecognized encoding logs a warning and falls back to IPA:

```python theme={null}
tts = GoogleTTS(
    custom_pronunciations=[
        {"phrase": "tomato", "pronunciation": "təˈmeɪtoʊ", "encoding": "ipa"},
        {"phrase": "Nginx", "pronunciation": "ˈɛndʒɪnˈɛks"},
    ]
)
```

<Note>
  Cloud TTS only applies custom pronunciations to `en-US`. With any other `languageCode` the
  plugin logs a warning and the overrides are ignored.
</Note>

They apply on both the streaming and non-streaming paths.

## Parameters

*Constructor parameters for `GoogleTTS`. The Python and Node JS SDKs share these field names.*

| Parameter               | Type                         | Default | Description                                                                                                                          |
| ----------------------- | ---------------------------- | ------- | ------------------------------------------------------------------------------------------------------------------------------------ |
| `voice_config`          | `dict \| None`               | `None`  | Voice selection — `name`, `languageCode`, `ssmlGender`. Unset means `en-US-Chirp3-HD-Charon` / `en-US` / `MALE`.                     |
| `model`                 | `str \| None`                | `None`  | Gemini-TTS engine, e.g. `"gemini-3.1-flash-tts-preview"`. Unset uses standard Cloud TTS, where the voice name determines the family. |
| `prompt`                | `str \| None`                | `None`  | Natural-language style instruction. Gemini-TTS only — `ValueError` without `model`.                                                  |
| `streaming`             | `bool`                       | `True`  | Use gRPC `StreamingSynthesize`. Restricted to Chirp 3 HD voices unless `model` is set, and cannot be combined with `vertexai`.       |
| `speed`                 | `float`                      | `1.0`   | Speaking-rate multiplier, passed through as `speaking_rate`. Cloud TTS accepts `0.25`–`4.0`.                                         |
| `pitch`                 | `float`                      | `0.0`   | Pitch shift in semitones, `-20.0`–`20.0`. Applied only when `streaming=False`.                                                       |
| `response_format`       | `Literal["pcm"]`             | `"pcm"` | Output encoding. `"pcm"` is the only accepted value.                                                                                 |
| `custom_pronunciations` | `list[dict] \| dict \| None` | `None`  | IPA or X-SAMPA pronunciation overrides. `en-US` only.                                                                                |
| `vertexai`              | `bool`                       | `False` | Route through the regional Vertex AI endpoint with ADC instead of the global API. Requires `streaming=False`.                        |
| `vertexai_config`       | `dict \| None`               | `None`  | `project_id` and `location` for Vertex AI.                                                                                           |

Output audio is fixed at 24 kHz, mono, 16-bit PCM — there is no `sample_rate` argument.

## Import paths

| SDK     | Import                                                    | Constructor          |
| ------- | --------------------------------------------------------- | -------------------- |
| Python  | `from zeroruntime.plugins import GoogleTTS`               | `GoogleTTS(...)`     |
| Node JS | `import { GoogleTTS } from '@zeroruntime/js-sdk/plugins'` | `GoogleTTS({ ... })` |

The same plugin is also reachable without a Google credential of your own, billed against your
Zero Runtime token, as `from zeroruntime.inference import GoogleTTS` — see
[Zero Runtime inference](/plugins/inference/zero-runtime).

The synthesized audio is streamed back to the caller as the final stage of the
[pipeline](/concepts/pipeline).
