---
title: "Refine the delivery of all of one character's lines on a table read artifact."
method: POST
path: "/artifacts/{artifactId}/performance"
tags: ["Artifacts"]
---

# Refine the delivery of all of one character's lines on a table read artifact.

`POST /artifacts/{artifactId}/performance`

## Request

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

Adjusts the performance — speed, volume, and cadence — across ALL of one character's lines on the live read backing a `table_read` artifact. How lines feel is their written acting directions (there are no emotion tags; on a Cartesia voice a direction is sent as one emotion from the voice's list): change one with POST /artifacts/{artifactId}/revoice-line. `emotions` and `overrideExisting` are refused with 400 `validation_failed`. Set `character` to a name, `"NARRATOR"` (all narration lines), or `"ALL"` (every voiced line). Speed and volume accept either an absolute value (`speed`, 1 the natural pace; `volume` 0.5–2.0) or a relative per-line multiplier (`speedFactor`/`volumeFactor`, e.g. `1.2` for +20%). Each line's speed is brought inside the range of the provider that speaks it (Cartesia 0.6–1.5, ElevenLabs 0.7–1.2, Deepgram 0.7–1.5), and a line whose voice takes no speed setting (OpenAI, Hume, Eleven v3, Cartesia before sonic-3, Deepgram Aura-1, a Cartesia professional clone) keeps its pace — `speedUnsupportedLines` counts them and `speedNote` says why. Volume clamps to 0.5–2.0. Provide at most one of each pair. There is no separate cadence field — express cadence as `speed` plus `pauseAfterMs` (breathing room after each line). No new revision — the artifact id and share URLs stay stable, like a voice recast. Durable media is invalidated; update the recording (POST /artifacts/{artifactId}/update-recording, free) to hear the change — only the lines it changed are spoken again.  Requires `Idempotency-Key`. Scope: `artifact:publish`.

## Headers

- `Idempotency-Key` string, required

## Request body

- PerformanceDirectiveRequest: Refine the delivery of all of one character's lines: speed, volume and pauses. Target a name, "NARRATOR" (all narration), or "ALL" (every voiced line). Provide at least one of speed/speedFactor/volume/volumeFactor/pauseAfterMs, and at most one of each speed/volume pair. How lines feel is their written acting directions: `emotions` and `overrideExisting` are refused with 400 `validation_failed`.
  - `character` string, required: Character name, "NARRATOR", or "ALL".
  - `speed` number: Absolute speed (1 is the voice's natural pace). Each line is brought inside the range of the provider that speaks it (Cartesia 0.6–1.5, ElevenLabs 0.7–1.2, Deepgram 0.7–1.5); a line whose voice takes no speed setting keeps its pace (`speedUnsupportedLines`). Mutually exclusive with speedFactor.
  - `speedFactor` number: Relative per-line speed multiplier (1.2 = +20%); each line is brought inside its own provider's range, and a voice with no speed setting keeps its pace. Mutually exclusive with speed.
  - `volume` number: Absolute volume slider. Mutually exclusive with volumeFactor.
  - `volumeFactor` number: Relative per-line volume multiplier; each line clamps to 0.5–2.0. Mutually exclusive with volume.
  - `pauseAfterMs` integer: Pause after each matched line, in ms (cadence/breathing room).
  - `instruction` string: Optional natural-language note recorded in the per-line audit trail.

## Response `200`

Performance directive applied.

- PerformanceDirectiveResponse: Result of a performance directive: how many of the character's lines matched and were updated, plus the resolved values applied.
  - `artifactId` string, required
  - `status` 'ready', required
  - `character` string, required: Resolved target ("ALL" when targeting every voiced line).
  - `matchedLines` integer, required
  - `linesUpdated` integer, required
  - `speed` number, nullable
  - `speedFactor` number, nullable
  - `volume` number, nullable
  - `volumeFactor` number, nullable
  - `pauseAfterMs` integer, nullable
  - `speedUnsupportedLines` integer: Matched lines whose voice takes no speed setting (OpenAI, Hume, Eleven v3, Cartesia before sonic-3, Deepgram Aura-1, a Cartesia professional clone): they keep their pace.
  - `speedNote` string, nullable: Why a line kept its pace, and what to do. Null when every matched line took the speed.

## 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 artifact is not in a state where this operation is valid yet (e.g. requesting an MP4 render before the share link exists).
- `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)
