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

# Summer Router: speech

> A line spoken in a character's voice. Call it from your game with Summer.client.router.speak(text: String, options: Dictionary = {"character": ""}).

A line spoken in a character's voice.

| | |
| - | - |
| In your game | `Summer.client.router.speak(text: String, options: Dictionary = {"character": ""})` |
| Status | Available |
| Metered | per character spoken, from the creator's Summer credits |
| Counts toward | per player per day, per game per day, per game per month, per account per month, per character per player per day, per character per game per day ([limits](https://docs.summerengine.com/router/limits.md)). A multiplayer server's calls count toward the game's caps, not the player's. |

## Example

```gdscript theme={null}
var r: SummerRouterResult = await Summer.client.router.speak("Welcome, traveller!", {"character": "narrator"})
if r.ok:
    $Voice.stream = r.audio
    $Voice.play()
```

The voice is the one you set on the character in Studio; `audio` is ready for an `AudioStreamPlayer`. To voice a reply the player just got, pass an empty text and `{"exchange_id": id}`: the SDK then sends the exchange instead of text.

## Input limits

The SDK builds the request from the call's arguments and options. Summer checks these limits:

| Field | Type | Limits |
| - | - | - |
| `text` | string | 1 to 5000 characters |
| `character` | string | The id of a character you made in Studio |
| `exchange_id` | string | The exchange\_id of a reply from the last hour |

Send `text` with `character`, or only `exchange_id` with an empty text.

## Errors

Every refusal has a stable tag and a one-line fix, and the game keeps running. See [errors](https://docs.summerengine.com/router/errors.md).


This documentation is built and hosted on [Mintlify](https://mintlify.com), a developer documentation platform.