---
title: "Hear a voice say a line before assigning it."
method: POST
path: "/voices/preview"
tags: ["Voices"]
---

# Hear a voice say a line before assigning it.

`POST /voices/preview`

## Request

- Base URL: `https://docs.sleeperhit.studio/api/v1`
- URL: `https://docs.sleeperhit.studio/api/v1/voices/preview`
- Auth: HTTP bearer

Voices any voice — one of yours (GET /voices) or a catalog voice — saying `text`, or a character's own first line in a read (`artifactId` + `character`), optionally with a `direction` (how to say it, in plain words), and answers with a playable `url`. On a Cartesia voice (sonic-3 and newer) the direction is sent as one emotion from the voice's list and a pace nudge, as a line's is: `sentAs` says which ("Sent as: sad, 0.9x"). Free. The same words in the same voice and delivery are voiced once: a repeat (or a line a deck already voiced) is served from cache (`cached: true`). Assign the voice afterwards with POST /artifacts/{artifactId}/voice or pin it with PATCH /story-projects/{projectId}/cast-canon.  Requires `Idempotency-Key`. Scope: `story:write`.

## Headers

- `Idempotency-Key` string, required

## Request body

- VoicePreviewRequest
  - `voiceId` string, required
  - `provider` 'cartesia' | 'elevenlabs' | 'openai' | 'deepgram' | 'hume': The voice's provider. Your own voices know theirs; otherwise the configured table-read provider.
  - `text` string: The words to hear. Omitted: `character`'s first line in the read `artifactId`.
  - `artifactId` string
  - `character` string
  - `direction` string: How to say it, in plain words — the way a line's acting direction is written. On a Cartesia voice it is sent as one emotion from the voice's list (`preview.sentAs`).

## Response `200`

The preview.

- VoicePreviewResponse
  - `preview` object, required
    - `voiceId` string, required
    - `provider` string, required
    - `text` string, required
    - `url` string, required: Playable audio.
    - `cached` boolean, required: true when these words in this voice and delivery had been voiced before, so nothing was bought.
    - `durationSeconds` number, nullable, required
    - `sentAs` object, nullable, required: What the `direction` was sent to the voice as: on a Cartesia voice (sonic-3 and newer) the mapping step's one emotion from the voice's list and the speed. Null when no direction was given or the voice takes no emotion.
      - `emotion` string, required: One emotion from the voice's fixed list.
      - `speed` number, required: The speed it was sent at: the line's own when set, else the direction's pace nudge, else 1.
      - `label` string, required: The one sentence every surface shows: "Sent as: sad, 0.9x".

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