---
title: "Re-voice one line of a table read at a new speed or with a new acting direction (free; TWO CALLS, quote first)."
method: POST
path: "/artifacts/{artifactId}/revoice-line"
tags: ["Artifacts"]
---

# Re-voice one line of a table read at a new speed or with a new acting direction (free; TWO CALLS, quote first).

`POST /artifacts/{artifactId}/revoice-line`

## Request

- Base URL: `https://docs.sleeperhit.studio/api/v1`
- URL: `https://docs.sleeperhit.studio/api/v1/artifacts/{artifactId}/revoice-line`
- Auth: HTTP bearer

Speaks line `entryIndex` again from its voice's provider with a new `speed`, a new `actingDirection`, or both (the line is spoken once). The speed is sent as that provider's OWN speed parameter (Cartesia `generation_config.speed` 0.6–1.5, ElevenLabs `voice_settings.speed` 0.7–1.2, Deepgram `speed` 0.7–1.5) — never a time-stretch — and brought inside the provider's range; the answer says the range (`range`) and whether it did (`clamped`). The direction is free text in the writer's words, sent through the provider's OWN expressive control: OpenAI `instructions`, ElevenLabs Eleven v3 and later as a leading audio tag, and Cartesia sonic-3 and newer as one emotion from the voice's list and a pace nudge, chosen from the direction's words by the mapping step when the line is spoken — GET /scripts/{scriptUploadId}/lines/{entryIndex} then shows it as `sentAs` (`direction` says which channel); an empty string or null takes it off. Every other line keeps its recording byte for byte, then the read is mixed again with its music and sound. FREE: a line's speed and direction cost no credits — nothing is held, charged or booked, and `credits` is always 0. Three outcomes (`mode`), all quoted first: `revoice` — the read has a finished recording, and the line is spoken again; `restore_take` — the line had a take with this speed and direction before (the take it has is kept whenever it is re-voiced), and it is brought back; `save` — the read has no recording yet: they are saved and the line is spoken that way when the read is recorded. TWO CALLS: sent without `confirmed` it QUOTES and changes nothing (`quotedOnly: true`, `credits` 0, `mode`, `changes`, `speed`, `previousSpeed`, `range`, `actingDirection`, `previousActingDirection`, `keptLines`, `balanceAfter`, `sufficient`, and a `note` to show the writer); sent again with `confirmed: true` it does it. Poll GET /artifacts/{artifactId} until `manifest.audio.finalize.status` is `complete`. Refused before the quote with 409 `cast_voice_precondition_failed` (`details.reason`): `provider_has_no_speed` (an OpenAI or Hume voice, or a model or voice with no speed setting — Eleven v3, Cartesia before sonic-3, a Deepgram Aura-1 voice or a Cartesia professional clone — named in `details.model` and `details.noSpeed`: recast the character first), `provider_has_no_direction` (a Deepgram, Hume, or OpenAI tts-1 voice, ElevenLabs before Eleven v3, or a Cartesia model before sonic-3 — none reads a written direction, and Cartesia before sonic-3 has no delivery controls at all — `details.model`, `details.noDirection`), `same_speed`, `same_direction`, `nothing_spoken`, `no_voice`, `modified_take` (the line plays a voice effect or a performance take), `finalize_running`, `not_spliceable` / `not_in_recording` (a recording that cannot be cut line by line), `line_changed` (the line was edited since it was priced). 409 `voice_retired` when the line's voice is one its provider retired.  Requires `Idempotency-Key`. Scope: `artifact:publish`.

## Headers

- `Idempotency-Key` string, required

## Request body

- RevoiceLineRequest: Give `speed`, `actingDirection`, or both: the line is spoken once.
  - `entryIndex` integer, required: The line: its index in the read (GET /artifacts/{artifactId}/script).
  - `speed` number: A new speed. 1 is the voice's natural pace; 1.15 is 15% faster. Brought inside the line's provider's range (Cartesia 0.6–1.5, ElevenLabs 0.7–1.2, Deepgram 0.7–1.5). Omit to keep the line's speed.
  - `actingDirection` string, nullable: A new acting direction: how the line is delivered, in the writer's words ("quiet, low-key storytelling tone"). Reaches OpenAI voices as `instructions` and ElevenLabs voices on Eleven v3 or later as a leading audio tag. An empty string or null takes it off. Omit to keep the line's direction.
  - `confirmed` boolean: Omit (or false) to get the quote (free: 0 credits) without changing anything. true does it, only after the writer has seen the quote and said go.

## Response `200`

The quote, 0 credits (no `confirmed`), or the queued re-voice / the saved speed and direction.

- RevoiceLineEnvelope
  - `quotedOnly` boolean, required: true when this call only QUOTED it.
  - `artifactId` string, nullable, required
  - `entryIndex` integer, required
  - `character` string, required: Who speaks the line: its character cue, or NARRATOR.
  - `text` string, required: The words spoken.
  - `voice` object, required
    - `voiceId` string
    - `voiceName` string, nullable
    - `provider` string
  - `changes` string[], required: What this changes: the line's speed, its acting direction, or both.
  - `speed` number, required: The speed the line is spoken at: the one asked for, inside the provider's range (its own, when the speed does not change).
  - `requestedSpeed` number, required
  - `clamped` boolean, required: true when the speed asked for was outside the provider's range.
  - `previousSpeed` number, required: The speed the line has now. Setting it back to this brings its current take back.
  - `range` object, nullable, required: The provider's speed range. Null: what speaks the line has no speed setting (only when the speed does not change).
    - `min` number
    - `max` number
    - `parameter` string: The provider's request field the speed is sent in.
  - `actingDirection` string, nullable, required: The acting direction the line is spoken with (its own, when the direction does not change). Null: none.
  - `previousActingDirection` string, nullable, required: The direction the line has now. Setting it back to this brings its current take back.
  - `direction` object, nullable, required: How the direction reaches the voice: a written channel (`instructions`, `audio_tag`) or, on Cartesia sonic-3 and newer, one `generation_config.emotion` (and a pace nudge) chosen from the direction's words by the mapping step — the line read's `sentAs`. Null: what speaks the line reads no direction (only when the direction does not change).
    - `channel` 'instructions' | 'audio_tag' | 'emotion'
    - `parameter` string: Where the provider reads the direction.
  - `mode` 'revoice' | 'restore_take' | 'save', required: All free. `revoice`: spoken again. `restore_take`: a take it had with this speed and direction comes back. `save`: no recording yet, the speed and direction are saved.
  - `keptLines` integer, required: Lines kept as they are in the current recording.
  - `credits` integer, required: Always 0: a line's speed and direction are free.
  - `costLabel` string, nullable: Quote only.
  - `balanceAfter` integer: Quote only. Studio Credits the writer would have left once this is spent: the balance available now (as Billing shows it) minus the price. Negative means they are that many short.
  - `sufficient` boolean: Quote only. True when the available balance covers the price. False means the writer must top up first (the note names the Billing link) — do not confirm; the reserve would refuse.
  - `note` string, required: What it would do, and that it is free (quote), or what happens next (confirmed). Show it to the writer.
  - `status` 'queued' | 'saved': Confirmed calls only. `queued`: poll GET /artifacts/{artifactId} until `manifest.audio.finalize.status` is complete. `saved`: the speed and direction are saved for the read's recording.

## Other responses

- `400`: Request payload failed validation. The error message names the offending field.
- `401`: Missing, malformed, revoked, or expired API key.
- `403`: API key is valid but lacks the scope, is blocked by IP allowlist, or the account is disabled.
- `404`: The story artifact does not exist or is owned by another account.
- `409`: The read or project is not ready for this cast voice operation, and nothing was priced or charged (`cast_voice_precondition_failed`): no description and no Series Bible voice line, a character with no lines, nothing to restore, no finished recording to re-voice, a voice the character already speaks with, a finalize already running, or a recording that cannot be cut line by line. The message says which and what to do; `project_precondition_failed` when the project gate holds spending.
- `429`: Rate limit for this API key + IP + route family was exceeded.
- `500`: The API failed unexpectedly. Safe to retry with the same Idempotency-Key.

---

[API](https://skmtc.dev/sleeperhit/apis/sleeper-hit-studio-story-api.md) · [All operations](https://skmtc.dev/sleeperhit/apis/sleeper-hit-studio-story-api/llms.txt) · [OpenAPI document](https://skmtc.dev/sleeperhit/apis/sleeper-hit-studio-story-api/revisions/4534f5d25540?raw)
