---
title: "Apply a voice effect to a range of lines on a table read artifact."
method: POST
path: "/artifacts/{artifactId}/voice-modification"
tags: ["Artifacts"]
---

# Apply a voice effect to a range of lines on a table read artifact.

`POST /artifacts/{artifactId}/voice-modification`

## Request

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

Applies a voice effect (currently only `autotune`) to a contiguous range of dialogue entries `[startEntryIndex..endEntryIndex]` on the live read backing a `table_read` artifact. No new revision — the artifact id and share URLs stay stable, like a voice recast. The autotune recipe (`params`) is optional and partial: any omitted field falls back to the proven defaults (key `D`, scale `minpent`, strength `1.0`, smooth `1`, reverb `chapel`). Async + queued: returns `{ artifactId, modificationId, status }`; the rendered audio is projected onto the read once the modification reaches `status: "ready"`.  Requires `Idempotency-Key`. Scope: `artifact:publish`.

## Headers

- `Idempotency-Key` string, required

## Request body

- VoiceModificationRequest: Apply a voice effect to a contiguous range of dialogue entries. The autotune recipe is optional and partial — any omitted field falls back to the proven defaults (key D, scale minpent, strength 1.0, smooth 1, reverb chapel).
  - `startEntryIndex` integer, required: First dialogue-entry index in the range (inclusive).
  - `endEntryIndex` integer, required: Last dialogue-entry index in the range (inclusive).
  - `effect` 'autotune': Voice effect to apply. Defaults to autotune (the only effect today).
  - `params` object: Partial autotune recipe; omitted fields fall back to the defaults.
    - `key` 'C' | 'C#' | 'D' | 'D#' | 'E' | 'F' | 'F#' | 'G' | 'G#' | 'A' | 'A#' | 'B'
    - `scale` 'major' | 'minor' | 'majpent' | 'minpent' | 'chromatic'
    - `strength` number: Pitch-correction strength, 0 (off) to 1 (full snap).
    - `smooth` integer: Pitch-glide smoothing; higher = slower glide.
    - `reverb` 'none' | 'light' | 'chapel'

## Response `200`

Voice modification dispatched.

- VoiceModificationResponse: Acknowledgement that a voice modification has been dispatched. Poll GET /artifacts/{artifactId} and read the matching record on `manifest.audio.modifications`: the rendered audio is projected onto entries once its `status` reaches `ready`, and its `error` carries the reason when it reaches `failed`.
  - `artifactId` string, required
  - `modificationId` string, required
  - `status` 'queued' | 'rendering' | 'ready' | 'failed', required: Lifecycle of the modification record.

## 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)
