---
title: "Judge a portrait design's headshots again."
method: POST
path: "/story-projects/{projectId}/cast-portraits/designs/{designId}/coverage"
tags: ["Projects"]
---

# Judge a portrait design's headshots again.

`POST /story-projects/{projectId}/cast-portraits/designs/{designId}/coverage`

## Request

- Base URL: `https://docs.sleeperhit.studio/api/v1`
- URL: `https://docs.sleeperhit.studio/api/v1/story-projects/{projectId}/cast-portraits/designs/{designId}/coverage`
- Auth: HTTP bearer

Looks at the headshots again as a new report, with the cast as it stands now. FREE: no price and no `confirmed`. A report already running is returned as it is. Refused (400) for a design with no drawn headshot, or when no provider can look right now. Requires `Idempotency-Key`. Scope: `story:write`.

## Headers

- `Idempotency-Key` string, required

## Request body

- CastingCoverageGenerateRequest
  - `focusPrompt` string: Optional: what to listen for hardest this time.

## Response `200`

The report now running (or the one already running).

- CastingPortraitCoverageResponse
  - `coverage` CastingPortraitCoverage, required: PORTRAIT CASTING COVERAGE of a portrait design: a model looked at every drawn headshot blind, beside the faces already chosen for the cast, and scored each on emblematic fit, period truth, naturalness (not generated) and distinctness. Choosing a headshot in `failingCandidates` is refused unless the writer chooses it anyway.
    - `status` 'missing' | 'generating' | 'complete' | 'failed', required
    - `kind` 'portrait', required
    - `projectId` string, required
    - `designId` string, required
    - `character` string, required
    - `keyCharacter` boolean, required
    - `available` boolean, required
    - `gateThreshold` number, required
    - `vetoDimensions` string[], required
    - `recommended` integer, nullable, required
    - `failingCandidates` integer[], required
    - `summary` string, required
    - `trigger` 'auto' | 'manual' | 'null', nullable, required
    - `reportId` string, nullable, required
    - `reportVersion` integer, nullable, required
    - `rubricVersion` integer, nullable, required
    - `model` string, nullable, required
    - `progressDetail` string, nullable, required
    - `failureMessage` string, nullable, required: Why the run stopped, as one plain sentence for the writer — never a provider's or the database's raw wording. Populated when `status: failed`.
    - `report` object, nullable, required: The ranking, every headshot (`candidate`, `candidateId`, `imageUrl`, `score`, `passed`, `flags`, `dimensions`, `problems`, `closestCastFace`), `recommended`, `runnerUp`, `close`, `allFail`, `redesign` ({ why, revisedDirection }), `verdict`, `references` and `judging`.
    - `createdAt` string, date-time, nullable, required
    - `updatedAt` string, date-time, nullable, required

## 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`: No portrait design with that id in this project (`portrait_design_not_found`), or the project is not yours (`project_not_found`).
- `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/86e084144cef?raw)
