# Say

The `<Say>` verb converts text to speech and plays it to the caller. Use it for spoken prompts, greetings, and instructions when you do not have a pre-recorded audio file.

## Attributes

| Name | Type | Default | Description |
|------|------|---------|-------------|
| `voice` | string | `man` | The voice used for speech synthesis. Accepts any string: PressOne does not validate `voice` against a fixed set of names. See [Voice selection](#voice-selection) for how each value is interpreted. |
| `language` | string | `en` | Accepted but not currently applied. Speech synthesis uses the default voice language regardless of this attribute. |
| `loop` | integer | `1` | Number of times to repeat the message. `0` repeats the message until the call ends, capped at 1,000 iterations. |

## Voice selection

Google Cloud Text-to-Speech is PressOne's default speech synthesis engine. The `voice` attribute is not restricted to an enum: PressOne inspects the string you supply and resolves it according to the rules below.

| `voice` value | Voice used |
|---|---|
| `man` (default) | Google male neural voice (`en-US-Neural2-I`). |
| `woman` or `alice`, matched exactly in lowercase | Google female neural voice (`en-US-Neural2-C`). |
| Any other bare string, including a typo or a capitalized variant such as `Woman` | Falls back to the Google male neural voice (`en-US-Neural2-I`). |
| `Google.<voice-name>` | The named Google Cloud Text-to-Speech voice, for example `Google.en-US-Wavenet-D`. |
| `Elevenlabs.<voice-id>` | The named ElevenLabs voice, spoken with the `eleven_v3` model. PressOne supplies the ElevenLabs API key from its own infrastructure: you do not pass one in the document. |

The provider name in front of the first period (`Google` or `Elevenlabs`) is matched without regard to case, and everything after that period is passed through unchanged as the voice name or ID. A `voice` value with a provider name PressOne does not recognize falls back to the default Google male voice and logs a warning on the server; the caller hears the fallback voice, not an error.

## Nesting

`<Say>` contains only the text to speak. It cannot contain nested verbs. `<Say>` may appear as a direct child of `<Response>`, or nested inside [`<Gather>`](/voice/oneml/gather) as an interruptible prompt.

## Examples

A plain greeting:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say>Thank you for calling PressOne support.</Say>
</Response>
```

Selecting an ElevenLabs voice by ID:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say voice="Elevenlabs.aRlmTYIQo6Tlg5SlulGC" language="en-US">Thank you for calling PressOne support.</Say>
</Response>
```

Selecting an explicit Google Cloud Text-to-Speech voice:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say voice="Google.en-US-Wavenet-D">Thank you for calling PressOne support.</Say>
</Response>
```

Repeating a message three times before continuing:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Say loop="3">Please stay on the line. An agent will be with you shortly.</Say>
  <Hangup/>
</Response>
```

`<Say>` nested inside [`<Gather>`](/voice/oneml/gather) as a menu prompt:

```xml
<?xml version="1.0" encoding="UTF-8"?>
<Response>
  <Gather action="/handle-menu" numDigits="1">
    <Say>For sales, press 1. For support, press 2.</Say>
  </Gather>
</Response>
```

## See also

- [Play](/voice/oneml/play)
- [Gather](/voice/oneml/gather)
- [OneML overview](/voice/oneml/overview)
