---
title: "Synthesise a spoken line as a WAV."
method: POST
path: "/api/agents/run/voice_speak"
tags: ["Production engines"]
---

# Synthesise a spoken line as a WAV.

`POST /api/agents/run/voice_speak`

## Request

- Base URL: `https://tomorrowlives.com`
- URL: `https://tomorrowlives.com/api/agents/run/voice_speak`
- Auth: HTTP bearer

Synthesises a line of English as a 44.1 kHz WAV with the engine's own voice. The voices are synthesised by the engine, never cloned from a recording, and no voice can be uploaded. seed varies the voice; woman, age (0 to 1) and machine shape it; speed (0.5 to 2) sets how fast it speaks (1 is the speaker's own); rate sets the sample rate. Every line comes back at one loudness (level_db, default -16 dBFS of speech, so lines from different voices sit together on a timeline and none clips; level_db false leaves the voice's own level) and with its silence trimmed to a breath either side (trim false keeps the voice's half-second tail). text is at most 1000 characters, and a line that presents itself as spoken by a real, famous person is refused. Costs 1 unit.

## Request body

- object
  - `text` string, required: The English line to speak, at most 1000 characters. A line that presents itself as spoken by a real, famous person is refused.
  - `seed` integer: A whole number that varies the voice.
  - `woman` boolean: True for a woman's voice, false for a man's.
  - `age` number: How old the voice sounds, 0 (young) to 1 (old).
  - `machine` boolean: True to give the voice a machine quality.
  - `speed` number: How fast it speaks, 0.5 to 2; 1 is the speaker's own pace.
  - `level_db` union: Loudness in dBFS of speech, -30 to -6 (default -16); false leaves the voice's own level.
    - number
    - false
  - `trim` boolean: False to keep the voice's half-second silent tail; the default trims silence to a breath either side.
  - `rate` 16000 | 22050 | 44100 | 48000: Sample rate in hertz: 16000, 22050, 44100 or 48000.

## Response `200`

The job's result and files

- Job
  - `job` string
  - `verb` string
  - `units` integer
  - `ms` integer
  - `result` unknown
  - `files` object[]
    - `name` string
    - `bytes` integer
    - `content_type` string
    - `url` string
    - `url_expires_at` string, date-time

## Other responses

- `400`: The input is not valid
- `401`: No valid API key
- `402`: A pass or a payment is needed: a queued render on the free plan, a unit pack on the free plan (pass_required), a card plan's past-due renewal, or, on the free plan, an owner who has not confirmed their email yet (owner_unconfirmed; a pass needs no confirmation); or a payment did not go through (payment_failed, payment_token_unusable), and nothing was charged
- `403`: The account is suspended, the paying card is not from the United States (region_not_supported), or the address named as its owner said it is not theirs and costed runs are paused until a new owner is named (owner_removed)
- `413`: The input or the output is over its cap; a job stopped by the output cap is not charged
- `422`: The engine refused the input, a limit of the service's refused it (error: video_limit or pull_limit) or stopped the job, or the content policy refused the input (error: content_policy)
- `429`: A limit was hit; reset_at says when it lifts (also in Retry-After)
- `503`: The engines are busy or not installed
- `504`: The job ran past its time and was stopped

---

[API](https://skmtc.dev/tomorrowlives/apis/tomorrow-lives-engines.md) · [All operations](https://skmtc.dev/tomorrowlives/apis/tomorrow-lives-engines/llms.txt) · [OpenAPI document](https://skmtc.dev/tomorrowlives/apis/tomorrow-lives-engines/revisions/afc3d67322ac?raw)
