---
title: Controlling voice delivery with steering tags — Inworld Realtime TTS-2 | Runware Docs
url: https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction
description: How to use natural-language steering tags to control emotion, pacing, volume, and vocal style in TTS-2 speech output.
---
### [Introduction](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#introduction)

Most text-to-speech models read words without considering how those words should sound. A farewell and a punchline come out with the same pitch, the same pacing, the same flat affect. The model knows *what* to say but has no concept of *how* to say it.

TTS-2 fixes this with **voice direction**: natural-language instructions, written in square brackets, that tell the model how to deliver a line. You write them the way you'd write a stage direction for an actor. There are no preset emotion slots, no dropdown menus, no sliders. If you can describe the delivery in plain English, the model can perform it.

[Listen to audio](https://runware.ai/docs/assets/intro-warm-greeting.BO1vvW63.mp3)

> **Prompt**: [speak warmly, as if greeting an old friend] Hey, it's been a while. How have you been?

### [How steering tags work](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#how-steering-tags-work)

A **steering tag** is a natural-language instruction enclosed in square brackets, placed before the text it applies to. The model reads the tag, adjusts its delivery, and speaks the text that follows.

The syntax is straightforward:

```text
[instruction] Text to speak.
```

The tag **applies forward** until the model reaches the next tag or the end of the input. You don't need to close it or reset it. If the mood shifts mid-text, drop a new tag at the transition point:

```text
[speak cheerfully] Great news, the build passed! [lower voice, more serious] But we need to talk about the memory leak.
```

Here's the full API request for that example:

TypeScriptPythoncURLCLIJSON

```typescript
import { createClient } from '@runware/sdk'

const client = await createClient({ apiKey: process.env.RUNWARE_API_KEY })
await client.connect()

const [result] = await client.run({
  model: 'inworld:tts@2',
  speech: {
    text: '[speak cheerfully] Great news, the build passed! [lower voice, more serious] But we need to talk about the memory leak.',
    voice: 'Sarah'
  }
})
```

```python
import asyncio
import os

from runware import Runware

async def main():
    async with Runware(api_key=os.environ["RUNWARE_API_KEY"]) as client:
        results = await client.run({
            "model": "inworld:tts@2",
            "speech": {
                "text": "[speak cheerfully] Great news, the build passed! [lower voice, more serious] But we need to talk about the memory leak.",
                "voice": "Sarah"
            }
        })

asyncio.run(main())
```

```bash
curl https://api.runware.ai/v1 \
  -H "Authorization: Bearer $RUNWARE_API_KEY" \
  -H "Content-Type: application/json" \
  -d '[
    {
      "taskType": "audioInference",
      "taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "model": "inworld:tts@2",
      "speech": {
        "text": "[speak cheerfully] Great news, the build passed! [lower voice, more serious] But we need to talk about the memory leak.",
        "voice": "Sarah"
      }
    }
  ]'
```

```bash
runware run inworld:tts@2 \
  speech.text="[speak cheerfully] Great news, the build passed! [lower voice, more serious] But we need to talk about the memory leak." \
  speech.voice=Sarah
```

```json
{
  "taskType": "audioInference",
  "taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
  "model": "inworld:tts@2",
  "speech": {
    "text": "[speak cheerfully] Great news, the build passed! [lower voice, more serious] But we need to talk about the memory leak.",
    "voice": "Sarah"
  }
}
```

Response

```json
{
  "data": [
    {
      "taskType": "audioInference",
      "audioUUID": "f1e2d3c4-b5a6-7890-1234-567890abcdef",
      "taskUUID": "a1b2c3d4-e5f6-7890-abcd-ef1234567890",
      "audioURL": "https://am.runware.ai/audio/os/a14d18/ws/2/ai/f1e2d3c4-b5a6-7890-1234-567890abcdef.mp3"
    }
  ]
}
```

[Listen to audio](https://runware.ai/docs/assets/mid-shift.CgDWjTcV.mp3)

> **Prompt**: [speak cheerfully] Great news, the build passed! [lower voice, more serious] But we need to talk about the memory leak.

### [Writing effective directions](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#writing-effective-directions)

Without any steering tags, the model reads text in a neutral, default tone. Adding a direction tag transforms the delivery. Compare the same line read flat versus with a detailed direction:

[Listen to audio](https://runware.ai/docs/assets/direction-minimal.Cwh1C8mB.mp3)

*No direction*

> **Prompt**: It's over. There's nothing left to say.

[Listen to audio](https://runware.ai/docs/assets/direction-detailed.DXUgAFUK.mp3)

*With direction*

> **Prompt**: [speak with deep sadness, voice low and hollow, as if holding back tears, long pauses between sentences] It's over. There's nothing left to say.

The directed version layers mood, rhythm, pitch, and vocal mode into a single instruction. Think of it as the difference between handing an actor a script versus giving them a scene brief. The more dimensions you describe, the more specific the performance.

> [!NOTE]
> You're writing stage directions, not keywords. The model responds to prose. Write the instruction the way you'd describe a read to a voice actor: "say this like you're confiding in a close friend late at night" works better than "intimate".

### [Direction categories](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#direction-categories)

Steering tags aren't limited to emotions. You can control multiple dimensions of delivery:

#### [Emotion](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#emotion)

Sets the overall mood. Can be a single word or a description:

```text
[say excitedly] We just hit a million users!
[sound concerned, speaking carefully] I'm not sure that's the right approach.
[sound terrified, barely holding it together] Did you hear that?
```

[Listen to audio](https://runware.ai/docs/assets/category-emotion-excited.CuWkvi7C.mp3)

> **Prompt**: [say excitedly] We just hit a million users!

[Listen to audio](https://runware.ai/docs/assets/category-emotion-terrified.MItEGDzb.mp3)

> **Prompt**: [sound terrified, barely holding it together] Did you hear that?

#### [Articulation and pacing](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#articulation-and-pacing)

Controls how clearly and at what speed words are delivered:

```text
[articulate clearly, with deliberate pauses] The API key goes in the Authorization header.
[very fast, urgent] We need to push the hotfix now, production is down.
[very slow, measured] Let me explain this one more time.
```

[Listen to audio](https://runware.ai/docs/assets/category-articulation.D1YWRIjm.mp3)

> **Prompt**: [articulate clearly, with deliberate pauses] The API key goes in the Authorization header.

[Listen to audio](https://runware.ai/docs/assets/category-pacing-urgent.hAm7s8Iy.mp3)

> **Prompt**: [very fast, urgent] We need to push the hotfix now, production is down.

#### [Volume and pitch](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#volume-and-pitch)

Shapes the intensity and register of the voice:

```text
[very quiet, almost a whisper] Don't tell anyone, but the feature ships tomorrow.
[say in a low tone, gravelly] This is your last warning.
[say in a high pitch, bright and cheerful] Good morning! Ready to get started?
```

[Listen to audio](https://runware.ai/docs/assets/category-volume-whisper.C_0f1Klr.mp3)

> **Prompt**: [very quiet, almost a whisper] Don't tell anyone, but the feature ships tomorrow.

#### [Vocal style](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#vocal-style)

Changes the mode of delivery itself:

```text
[whisper in a hushed style] I think someone's listening.
[give a nasal quality, slightly annoyed] Ugh, another meeting.
```

[Listen to audio](https://runware.ai/docs/assets/category-style-whisper.DD_V6KaY.mp3)

> **Prompt**: [whisper in a hushed style] I think someone's listening.

#### [Combining dimensions](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#combining-dimensions)

The best results come from combining qualities across multiple categories in a single tag. Layer mood, pitch, pacing, and manner together:

[Listen to audio](https://runware.ai/docs/assets/combined-sad.FR7MP_ZY.mp3)

> **Prompt**: [say sadly with deliberate pauses in a low voice and hushed style] I don't think he's coming back.

[Listen to audio](https://runware.ai/docs/assets/combined-excited.BnAgbCor.mp3)

> **Prompt**: [speak quickly with excitement and a high pitch] Oh my god, you won't believe what just happened!

[Listen to audio](https://runware.ai/docs/assets/combined-calm.DggPzT0n.mp3)

> **Prompt**: [calm and steady, with a warm tone and measured pace] Take a deep breath. We'll figure this out together.

### [Inline non-verbals](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#inline-non-verbals)

You can also insert **non-verbal sounds** at specific points in the text. These are placed inline, exactly where the sound should occur:

```text
Wait, you actually did that? [laugh] That's wild.
[sigh] I don't know. It's been one of those weeks.
Okay, let me think about this for a second. [breathe] Right. Here's what we do.
```

The available non-verbals are `[laugh]`, `[sigh]`, `[breathe]`, `[clear throat]`, `[cough]`, and `[yawn]`. They work as **audio events**, not pronounced words. The model inserts the sound at that position and continues speaking.

[Listen to audio](https://runware.ai/docs/assets/nonverbal-laugh.BeYZPepA.mp3)

> **Prompt**: Wait, you actually did that? [laugh] That's wild.

[Listen to audio](https://runware.ai/docs/assets/nonverbal-sigh.DSX2aFD6.mp3)

> **Prompt**: [sigh] I don't know. It's been one of those weeks.

You can combine non-verbals with steering tags. The tag sets the delivery, the non-verbal inserts a specific moment:

[Listen to audio](https://runware.ai/docs/assets/nonverbal-combined.dsJyB5IQ.mp3)

> **Prompt**: [speak tiredly, end-of-day energy] [sigh] I don't know. It's, uh, it's been one of those weeks where you just kind of... lose the thread.

### [Emphasis and pacing](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#emphasis-and-pacing)

Two text-level techniques complement steering tags and work in any TTS-2 request, with or without bracket tags.

#### [Capitalization for stress](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#capitalization-for-stress)

**Capitalize a word** to make the model stress it. This works the way bold or italics would in written text, drawing the listener's ear to the important word:

```text
I told you NOT to do that.
Your order will arrive by FRIDAY.
That is AbsoLUTEly correct.
```

**Full-word capitalization** stresses the entire word. **Partial capitalization** (like "AbsoLUTEly") stresses a specific syllable. Use both sparingly. If everything is emphasized, nothing is.

[Listen to audio](https://runware.ai/docs/assets/emphasis-caps.B-u47714.mp3)

> **Prompt**: I told you NOT to do that.

#### [Punctuation for pacing](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#punctuation-for-pacing)

The model responds to punctuation the same way a reader does. **Periods** create full pauses. **Commas** create shorter breaks. **Ellipses** create a trailing, lingering pause, and work well for hesitation or uncertainty:

```text
I thought it would work, but... I'm not so sure anymore.
Stop. Think. Then act.
Well, when you put it that way, I suppose you might have a point.
```

[Listen to audio](https://runware.ai/docs/assets/pacing-ellipsis.7U5uPGDb.mp3)

> **Prompt**: I thought it would work, but... I'm not so sure anymore.

### [Common mistakes](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#common-mistakes)

#### [Contradicting the content](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#contradicting-the-content)

A steering tag should match the text it applies to. Tagging `[sound happy and excited]` on a line about a funeral degrades the output because the model is pulled in two directions. If the text is somber, the tag should reflect that.

#### [Combining opposing directions](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#combining-opposing-directions)

Keep each tag internally consistent. Pairing `[whisper in a hushed style]` with `[very loud]` in the same instruction sends conflicting signals. Pick one direction per tag. If you need the mood to shift, use a new tag at the transition point.

#### [Over-tagging](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#over-tagging)

You don't need a tag on every sentence. A single tag carries forward until the next one. If five consecutive sentences should all feel warm and conversational, one tag at the start is enough. Changing direction every sentence produces a jittery, unnatural read.

### [Tips for best results](https://runware.ai/docs/models/inworld-tts-2/guides/voice-direction#tips-for-best-results)

1. **Write stage directions, not keywords.** "Say this like you're apologizing to someone you care about" outperforms "apologetic". The model responds to prose, so give it a scene.
    
2. **Combine at least two dimensions.** Mood alone is generic. Mood plus pacing, or mood plus volume, produces a more specific delivery. "Sad" is vague. "Sad, quiet, with long pauses" is a read.
    
3. **Place non-verbals where a human would do them.** A `[sigh]` at the start of a resigned sentence, a `[laugh]` after a punchline. Don't scatter them randomly.
    
4. **Use capitalization for one or two words per sentence at most.** Emphasis works because it's selective. Capitalizing half the sentence removes the contrast that makes it effective.
    
5. **Test with the same voice.** Different voices respond to the same direction with different intensity. A direction that sounds perfect on Sarah might feel understated on Ethan. Pick your voice first, then tune the directions to it.
    
6. **Let the model breathe.** Longer input with natural punctuation sounds better than short fragments stitched together. Give the model a full thought to work with, not a word at a time.