---
title: "Price, then make, living portraits for the title intros."
method: POST
path: "/pitch-decks/{jobId}/title-sequence/motion-closes"
tags: ["Pitch Deck"]
---

# Price, then make, living portraits for the title intros.

`POST /pitch-decks/{jobId}/title-sequence/motion-closes`

## Request

- Base URL: `https://docs.sleeperhit.studio/api/v1`
- URL: `https://docs.sleeperhit.studio/api/v1/pitch-decks/{jobId}/title-sequence/motion-closes`
- Auth: HTTP bearer

A motion close is a person's LIVING PORTRAIT for their title intro: one WAN shot of their face and shoulders from their cast portrait, the person looking straight into the lens and holding still — breath, an occasional blink, lips closed — lit and graded like the deck (its Series Bible's look), at 480p, silent, 3 seconds on the 2 s bell (the flash's beat plus room), in shadow when the sequence keeps them in shadow. PRICED FIRST — TWO CALLS on the API and the CLI, two tools on MCP and in chat (quote_render_pitch_deck_title_motion_closes, then render_pitch_deck_title_motion_closes): without `confirmed` it prices every person whose intro is not yet their living portrait (`motionClosesNeeded` in the read: about 6 people × 3 s at 480p for a father and his sons), or the people named in `names` (a new take of someone who has one is priced again), and spends nothing; with `confirmed: true` it reserves exactly those lines and renders them. Allowed while the deck is in review or complete. When each lands it is checked like a take (a file that decodes, silent, its length) and the master is re-assembled with it, free; a render that fails or is refused is released (nothing charged). Read each one back as `titleSequence.motionCloses` (`livingPortrait` false: a moving close made before 2026-10-07, which no longer opens an intro). Refused before the price: a deck that has not rendered, no title sequence, every intro already its living portrait, a name the sequence does not have (400), a person whose living portrait is already on its way, a person with no cast portrait to render from, or a portrait prompt row not yet rolled out — with the fix in `details.refusal`. Requires `Idempotency-Key`. Scope: `artifact:publish` — a read-only key can neither spend nor ask what spending would cost.

## Headers

- `Idempotency-Key` string, required

## Request body

- PitchDeckTitleMotionClosesRequest
  - `names` string[]: The people to make one for, named as the title sequence names them. Left out: everyone in `titleSequence.motionClosesNeeded`.
  - `confirmed` boolean: Left out: price only, nothing reserved. True: reserve exactly the priced lines and render them.

## Response `200`

The price (no `confirmed`) or the queued living portraits.

- PitchDeckTitleMotionClosesAnswer: The price (`quotedOnly: true`, with `lines`, `balanceAfter`, `sufficient`, `note`, `costLabel`) or the queued renders (`quotedOnly: false`, `queued: true`, `names`, `message`).
  - `quotedOnly` boolean, required
  - `queued` boolean
  - `jobId` string, required
  - `credits` number, required
  - `costLabel` string, nullable
  - `balanceAfter` number
  - `sufficient` boolean
  - `note` string
  - `names` string[]
  - `message` string
  - `lines` object[]
    - `name` string, required
    - `take` integer, required
    - `seconds` number, required
    - `credits` number, required
    - `idempotencyKey` string, required

## 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 pitch deck exists and the request is well-formed, but the deck, its chapter, its cast or its plates are not in a state that allows it (`pitch_deck_state_invalid`), and nothing was reserved: a plan approved outside draft, a take chosen, a chapter edited or rendered outside review/complete, an export before the finish, a finish while a call has no selected take or a footage chapter has not rendered, a text-only chapter asked for footage, a changed chapter asked for one call, a delivery class changed mid-pass, a render the compile blocked, or a finish while the master failed its video coverage (`pitch_deck_video_coverage_failed`, with `details.videoCoverage`). `details.refusal` is `{ code, action, fix }` (see PitchDeckRefusalDetails): `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 chapter a blocked compile could not render. The identical request succeeds once the deck 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)
