---
title: "Read the enriched cast for a table read artifact."
method: GET
path: "/artifacts/{artifactId}/cast"
tags: ["Artifacts"]
---

# Read the enriched cast for a table read artifact.

`GET /artifacts/{artifactId}/cast`

## Request

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

Returns the enriched cast for the read backing this artifact: each character's assigned voice (`voiceId` / `voiceName` / `gender` / `provider`) merged with its avatar state (`avatarUrl` / `avatarStyle` / `avatarStatus`), plus the artifact's resolved top-level `avatarStyle`. `avatarStatus` is `none` (no avatar), `queued` / `rendering` (a render is in flight), `ready`, or `failed` — poll this endpoint after recast_avatar / update_cast until in-flight renders reach `ready`. The cast is assigned automatically when the table read becomes performable; an empty `cast` means it is not performable yet (poll GET /artifacts/{artifactId}). `identity` warns when one character reaches two canon people or two people share a body figure, lists characters with no Series Bible appearance, and lists Series Bible names no canon person answers to (`unresolvedBibleNames`, with candidates). It is read-only; fix it by declaring aliases on the cast canon. `restorable` lists each character recast on this read whose previous voice (and recording, when `recordingRecoverable`) POST /artifacts/{artifactId}/voice/restore can put back.  Scope: `artifact:read`.

## Response `200`

Enriched cast envelope.

- CastEnvelope: Enriched cast for a table read artifact: each character's voice merged with its avatar state, plus the resolved episode portrait override when present.
  - `artifactId` string, required
  - `cast` EnrichedCastEntry[], required
    - `character` string, required
    - `voiceId` string, nullable, required
    - `voiceName` string, nullable, required
    - `gender` string, nullable, required
    - `provider` string, nullable, required
    - `avatarUrl` string, uri, nullable, required
    - `avatarStyle` string, nullable, required: The art-direction this character's avatar was rendered against.
    - `avatarStatus` 'none' | 'queued' | 'rendering' | 'ready' | 'failed', required: `none` (no avatar), `queued` / `rendering` (a render is in flight), `ready`, or `failed`. Poll until `ready` after a render.
    - `avatarVideoUrl` string, uri, nullable, required: The animated talking portrait (a short loop), when one was made (POST /artifacts/{artifactId}/avatar-video).
    - `avatarVideoStatus` 'none' | 'queued' | 'rendering' | 'ready' | 'failed', required: The animated portrait's render: `none` (never asked for), `queued` / `rendering`, `ready`, or `failed`.
  - `avatarStyle` string, nullable, required: The artifact's explicit episode portrait override (`table_read_avatar_style`). Project-level visual canon lives in the Series Bible. `null` when no override exists.
  - `identity` CastIdentityReport, required: Identity warnings on a cast read. Read-only: nothing is merged, generated or charged.
    - `duplicates` object[], required: One name that reaches two or more canon people (a key two people claim, or a person with no name of their own beside another, like FYODOR beside Fyodor Karamazov), or two people sharing one body figure. Fix it by keeping one person and listing the other names as aliases.
      - `kind` 'one_character_two_people' | 'shared_figure', required
      - `character` string, nullable, required: The name that reaches more than one person; null for a shared figure.
      - `people` string[], required: The people involved, by display name.
      - `figureUrl` string, nullable, required: The shared body figure; null for one_character_two_people.
      - `message` string, required
    - `noBibleAppearance` object[], required: Characters with no appearance or wardrobe in the Series Bible: a video would describe them by name only.
      - `character` string, required
      - `message` string, required
    - `unresolvedBibleNames` object[], required: Series Bible names that no cast canon person answers to by name or alias ("Foma Stepanovich" beside the canon's FOMA), each with the canon people it probably is. A voice or body shot asked for under the Bible name is not found. Fix it by adding the Bible name to that person's `aliases` on the cast canon; nothing is resolved automatically.
      - `bibleName` string, required: The Series Bible's name for the character.
      - `candidates` string[], required: Canon people (display names) one of whose names is wholly contained in the Bible name.
      - `message` string, required
  - `restorable` RestorableVoice[], required: Characters recast on this read whose previous voice POST /artifacts/{artifactId}/voice/restore can put back, newest recast per character.
    - `character` string, required
    - `historyId` string, required
    - `at` string, date-time, required
    - `previousVoiceId` string, nullable, required: The voice a restore puts back; null when the character had none.
    - `previousVoiceName` string, nullable, required
    - `currentVoiceName` string, nullable, required
    - `recordingRecoverable` boolean, required: A restore also brings back the recording the read had before the recast.

## Other responses

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