---
title: "Price, then compose, a score to the trailer's cut."
method: POST
path: "/trailers/{jobId}/score-to-picture"
tags: ["Trailer"]
---

# Price, then compose, a score to the trailer's cut.

`POST /trailers/{jobId}/score-to-picture`

## Request

- Base URL: `https://docs.sleeperhit.studio/api/v1`
- URL: `https://docs.sleeperhit.studio/api/v1/trailers/{jobId}/score-to-picture`
- Auth: HTTP bearer

Composes ONE score to the trailer's cut — a cue sheet planned over its beats (sections that change on the cuts, an intensity curve, hit points at chosen cuts, room under every spoken line, the Series Bible's tone and period), a composition conformed to the master's length to the frame — and lays it under the whole master in place of the table read's scene beds, then re-stitches the master through its serialized assembly. TWO CALLS, PRICE FIRST: sent WITHOUT `confirmed` it prices the score and holds nothing (`quotedOnly: true`, `credits`, `balanceAfter`, `sufficient`, `note`); sent again with `confirmed: true` it holds the quoted credits and starts composing. On a DRAFT plan (so the music direction is set before anything renders) or while the first render pass is still running, it is priced on the PLANNED cut and waits for that pass's master (`waiting_for_master`), and a SKETCH to the planned cut is composed right away by the same planner and composer — free, never laid — to listen to (`sketch.url` on the read). Priced like the app's other music generation: included today (0 credits), still quoted first. Refused with a 409 before any price when the writer placed music of their own or edited an earlier score (the writer's music is never replaced), or while a score is already composing. `direction` is an optional note on the music the writer wants. Requires `Idempotency-Key`. Scope: `artifact:publish`.

## Headers

- `Idempotency-Key` string, required

## Request body

- object
  - `confirmed` boolean: Omit (or false) for the price; true only after the writer has seen it and said go.
  - `direction` string: An optional note on the music the writer wants.

## Response `200`

The price (no `confirmed`), or the started score. On a trailer with no screenplay whose video a blank beat holds, the started score lands on the timeline and answers `masterHold` (the video is not stitched again until each blank beat is fixed).

- object

## Other responses

- `400`: Request payload failed validation. The error message names the offending field.
- `401`: Missing, malformed, revoked, or expired API key.
- `402`: Not enough Studio Credits to reserve this job (`insufficient_credits`), and nothing was reserved. `details` is InsufficientCreditsDetails: `required` and `available`, and `autoTopup` when auto top-up is on but did not cover it — `pending` (retry in a moment), `over_cap` (raise the monthly spending cap), `too_small` (buy a bigger pack) or `failed`.
- `403`: API key is valid but lacks the scope, is blocked by IP allowlist, or the account is disabled.
- `404`: The named project or source does not exist or is owned by another account.
- `409`: The trailer exists and the request is well-formed, but the trailer, its beat, its cast or its plates are not in a state that allows it (`trailer_state_invalid`), and nothing was reserved: a plan approved outside draft, a take chosen or a beat rendered outside review/complete, an export before the finish, a finish while a call has no selected take, a narrated cut with no narrator, a render the compile blocked, or a finish while the master failed its video coverage (`trailer_video_coverage_failed`, with `details.videoCoverage`). `details.refusal` is `{ code, action, fix }` (see TrailerRefusalDetails): `action` is what unblocks it — `recast_figure`, `add_signature_items`, `recast_voice` or `remake_location_plate` — and `fix` names the MCP tool and CLI command that take it; `details.blocked[]` lists every beat a blocked compile could not render. The identical request succeeds once the trailer is put right.
- `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)
