---
title: "Let the deck's automatic fixes try more (priced: one more allowance grant)."
method: POST
path: "/pitch-decks/{jobId}/more-fixes"
tags: ["Pitch Deck"]
---

# Let the deck's automatic fixes try more (priced: one more allowance grant).

`POST /pitch-decks/{jobId}/more-fixes`

## Request

- Base URL: `https://docs.sleeperhit.studio/api/v1`
- URL: `https://docs.sleeperhit.studio/api/v1/pitch-decks/{jobId}/more-fixes`
- Auth: HTTP bearer

The render approval carries an automatic-fix allowance: the engine watches the 480p preview and retakes the shots its review flags, inside that ceiling, until the preview is clean or it stops short (GET /pitch-decks/{jobId}/chapters `autoFix`: `state: stopped`, `stopReason`, `stoppedBecause`). When it stopped for want of credits or rounds, or because a flagged shot reached its tries, `autoFix.moreFixes` offers ONE MORE GRANT and `verdict.choices` carries `more_fixes`. METERED, TWO CALLS: without `confirmed` it PRICES the grant and reserves nothing (`quotedOnly: true`, `credits`, `costLabel`, `balanceAfter`, `sufficient`, `note`; when `sufficient` is false do not confirm); with `confirmed: true` it reserves it, raises the loop's caps (a round of fixes and a try per shot more) and the loop answers the same review again (`quotedOnly: false`, `queued: true`, `message`, `autoFix`). Only what the fixes draw is charged; the rest comes back when the loop stops. Refused with 409 `pitch_deck_state_invalid` (`details.refusal.code`: `auto_fix_not_in_review`, `auto_fix_nothing_more` — still fixing, or nothing a new take or a text render would fix: finish anyway instead — `auto_fix_already_running`), 402 when the balance cannot hold the grant. Review only. Requires `Idempotency-Key`. Scope: `artifact:publish`.

## Headers

- `Idempotency-Key` string, required

## Request body

- MoreFixesRequest: Let the automatic fixes try more. Metered, two calls: omit `confirmed` for the price; send `confirmed: true` only after the writer has seen it and said go.
  - `confirmed` boolean: Omit (or false) to get the price WITHOUT spending anything. Send true only after the writer has seen that price and said go.

## Response `200`

The price of one more grant, or the grant reserved and the loop running again.

- MoreFixesAnswer: Either the PRICE of one more automatic-fix grant (`quotedOnly: true`; nothing reserved) or the grant itself (`quotedOnly: false`, `queued: true`: reserved, and the loop answers the same review again).
  - `quotedOnly` boolean, required
  - `queued` boolean: Confirmed call only.
  - `jobId` string, required
  - `credits` integer, required: What the grant holds: only what the fixes draw is charged.
  - `costLabel` string, nullable: Quote only.
  - `balanceAfter` integer: Quote only. Studio Credits the writer would have left once this is spent: the balance available now (as Billing shows it) minus the price. Negative means they are that many short.
  - `sufficient` boolean: Quote only. True when the available balance covers the price. False means the writer must top up first (the note names the Billing link) — do not confirm; the reserve would refuse.
  - `note` string: Quote only: the price in the writer's own words.
  - `message` string: Confirmed call only.
  - `autoFix` AutoFix: `autoFix` is the AUTOMATIC FIXES: the approval quote carries an automatic-fix allowance for paid fixes beside the 480p render (`autoFixAllowance`), reserved with it — none for a cut with nothing a new take could redo (app captures, title cards) or a balance that holds only the render. FREE FIXES RUN WHATEVER THE ALLOWANCE: an app capture's narration the review hears off its picture is laid again on it (`kind: retime`, 0 credits), and a capture beat whose line is cut at the cut (or has no room to land on its press) keeps more of its recording (`kind: stretch`, 0 credits), and one whose picture goes blank for a frame at its start or end keeps a stretch that does not show it (`kind: trim`, 0 credits), and a unit whose narration is measured under the music has the music under it lowered (`kind: duck`, `duckDb`, 0 credits); free fixes run on a review that cleared the bar and after the rounds are run too. After the preview is stitched the engine watches it (video coverage) and retakes the shots the review flags — each new take told what the review saw, a shot at most twice, re-staged as a voice-over where the take rules allow — and renders flagged on-screen text again, inside the allowance; then it stitches and watches the preview again. It stops at a clean 480p preview (`state: clean`), when the allowance is spent (`no_allowance` when none was held), when the review flags nothing a fix can clear, or after `maxRounds` rounds (`state: stopped`, `stopReason`, `stoppedBecause`). `state` is `waiting` (first pass rendering), `reviewing` or `fixing` while it works — do not retake or finish then, just poll. `allowanceCredits` is the ceiling, `drawnCredits` what fixes took from it (each charged only when its take lands), `heldCredits` what is still reserved (released when it stops); `rounds[]` lists each round's fixes with `why`. When it stopped short, `moreFixes` (if not null) offers one more grant of `credits` (the more-fixes op, priced first); otherwise the writer finishes anyway. The 720p finish is always the writer's own approval.
    - `state` 'waiting' | 'reviewing' | 'fixing' | 'clean' | 'stopped', required: `waiting` (the first pass renders), `reviewing` (the preview is being watched), `fixing` (fixes are rendering), `clean`, or `stopped`.
    - `stopReason` 'clean' | 'allowance_spent' | 'cannot_clear' | 'rounds_spent' | 'review_unavailable' | 'writer_stopped' | 'finished' | 'no_allowance' | 'deleted' | 'null', nullable, required: Why it stopped (null while it works).
    - `allowanceCredits` integer, required: The ceiling approved for fixes: every grant together.
    - `drawnCredits` integer, required: What fixes drew from it (each charged only when its take lands; back to the writer when it fails).
    - `heldCredits` integer, required: What the allowance still holds for fixes; 0 once it stops (released).
    - `round` integer, required: Rounds of fixes run, never more than `maxRounds` (free fixes after the rounds are listed in `rounds` without counting as one).
    - `maxRounds` integer, required: The most rounds it runs.
    - `fixesInFlight` integer, required: Fixes still rendering.
    - `rounds` object[], required: Each round: the review it answered and the fixes it applied.
      - `round` integer, required
      - `reportId` string, nullable, required: The video coverage report it answered.
      - `overallScore` number, nullable, required
      - `startedAt` string, date-time, required
      - `fixes` object[], required
        - `kind` 'retake' | 'text' | 'retime' | 'stretch' | 'trim' | 'duck', required: `retake`: a new take of a shot; `text`: the unit's on-screen text rendered again; `retime`: an app capture's narration laid again on its picture; `stretch`: more of an app capture's recording kept so its narration fits (cut at the cut, or no room to land on its press); `trim`: an app capture's kept stretch moved off a blank frame measured at its start or end (`trim`); `duck`: the music under a unit whose narration was measured under it lowered by `duckDb`. `retime`, `stretch`, `trim` and `duck` are free, whatever the allowance.
        - `unitIndex` integer, required: The chapter's or beat's key.
        - `unitNumber` integer, required: Its place in the cut.
        - `callId` string, nullable, required
        - `take` integer, nullable, required
        - `credits` integer, required: What it drew from the allowance (0 when it could not start).
        - `ended` boolean, required: Its job has ended (landed, failed or refused).
        - `why` string[], required: What the review saw that it answers; a retake is told to avoid it.
        - `trim` object, nullable, required: `trim` only: the end of the beat the blank frames sat at and how many; null for every other kind.
          - `edge` 'head' | 'tail', required
          - `frames` integer, required
        - `duckDb` number, nullable, required: `duck` only: how many dB the music under the unit was lowered; null for every other kind.
    - `moreFixes` object, nullable, required: When it stopped short and one more grant could help: what that grant would hold (POST …/more-fixes). Null otherwise.
      - `credits` integer, required
    - `stoppedBecause` string, nullable, required: Why it stopped short of clean, in plain words.
    - `sentence` string, required: Where it stands, in one sentence.

## Other responses

- `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/4534f5d25540?raw)
