---
title: "Preview where a take would record (admins only)."
method: POST
path: "/admin/capture-runners/preview"
tags: ["Admin"]
---

# Preview where a take would record (admins only).

`POST /admin/capture-runners/preview`

## Request

- Base URL: `https://docs.sleeperhit.studio/api/v1`
- URL: `https://docs.sleeperhit.studio/api/v1/admin/capture-runners/preview`
- Auth: HTTP bearer

A take records where it fits: a page drawn at 40 fps or more on a plain machine is light and goes to Browser Run (or a CPU runner); a heavier page, or one whose own sound is recorded, needs a runner that can (a GPU, PulseAudio or SleeperAudioTap). Allow-listed connections send their heavy (or unmeasured) pages to a shared-host GPU runner first, and their light pages there only when nothing else may take them. A busy or degraded runner hands the take to the next candidate; a take whose picture still stutters is re-recorded once on a heavier runner. A preview: nothing is recorded or changed. 404 `not_found` for an unknown connection. Scope: `account:read`. Free.

## Request body

- CaptureRouteRequest
  - `purpose` 'record' | 'sign-in-test'
  - `connectionId` string, nullable: The app connection the take signs in with; omit for one of Sleeper's own takes.
  - `sound` 'off' | 'app'
  - `drawFps` number, nullable: The smoothness preflight's draw rate for the tour's opening page; omit when not measured.
  - `runner` string, nullable: `auto`, a runner's name, or `browser-run`: refused (never rerouted) when it breaks a hard rule.

## Response `200`

The route: its candidates in order, or why none may take it.

- CaptureRoute
  - `ok` boolean, required
  - `heavy` boolean, nullable, required: Whether the page needs a GPU recorder; null when not measured.
  - `needs` string[], required
  - `candidates` object[]: When ok: where it would record, in the order tried.
    - `kind` 'runner' | 'browser-run', required
    - `name` string
  - `code` 'no_recorder' | 'override_refused': When not ok.
  - `reason` string: When not ok: why, in plain words.
  - `reasons` string[], required: Why each runner was or was not picked.

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