---
title: "Save the deliverable's surface scout."
method: POST
path: "/story-projects/{projectId}/deliverables/{deliverableId}/scout"
tags: ["Projects"]
---

# Save the deliverable's surface scout.

`POST /story-projects/{projectId}/deliverables/{deliverableId}/scout`

## Request

- Base URL: `https://docs.sleeperhit.studio/api/v1`
- URL: `https://docs.sleeperhit.studio/api/v1/story-projects/{projectId}/deliverables/{deliverableId}/scout`
- Auth: HTTP bearer

Save the deliverable's surface scout: `scout` is the ranked-moments document of the destination surface, validated against the shared spec — an unknown moment kind or any other malformed field is a named 400 and NOTHING is stored. A valid save writes THIS deliverable's own `scout` column, so a re-write updates the same row and no sibling deliverable is touched.

## Request body

- object
  - `scout` object, required: Ranked surface moments, in rank order: `{ id, tool, kind, why, evidence[], legibilityEstimate, setupNeeded, risk }` per moment. Validated against the shared `surfaceScoutSchema`; an unknown moment kind or any other malformed field is a named 400 and nothing is stored.
    - `moments` object[], required
      - `id` string, required: Snake-case moment id (`^[a-z][a-z0-9_]{0,63}$`, at most 64 chars), unique within the document — a duplicate id is refused with the same named 400.
      - `tool` string, required: The tool this moment films. Trimmed by the validator: it must contain a non-whitespace character.
      - `kind` 'widget_render' | 'approval_prompt' | 'quote' | 'list' | 'refusal', required: What filming this moment shows: `widget_render`, `approval_prompt`, `quote`, `list` or `refusal`.
      - `why` string, required: Why the moment earns its rank. Trimmed by the validator: it must contain a non-whitespace character.
      - `evidence` object[], required
        - `kind` 'tool_annotation' | 'output_template_present' | 'route' | 'checkpoint', required
        - `detail` string, required: The receipt a reviewer (or the cut) can check the moment against. Trimmed by the validator: it must contain a non-whitespace character.
      - `legibilityEstimate` string, required: The human estimate of on-screen legibility. Trimmed by the validator: it must contain a non-whitespace character.
      - `setupNeeded` boolean, required
      - `risk` object, required
        - `spend` boolean, required
        - `destructive` boolean, required

## Response `200`

The saved scout, stored on the deliverable itself.

- object
  - `scout` object, required: Ranked surface moments, in rank order: `{ id, tool, kind, why, evidence[], legibilityEstimate, setupNeeded, risk }` per moment. Validated against the shared `surfaceScoutSchema`; an unknown moment kind or any other malformed field is a named 400 and nothing is stored.
    - `moments` object[], required
      - `id` string, required: Snake-case moment id (`^[a-z][a-z0-9_]{0,63}$`, at most 64 chars), unique within the document — a duplicate id is refused with the same named 400.
      - `tool` string, required: The tool this moment films. Trimmed by the validator: it must contain a non-whitespace character.
      - `kind` 'widget_render' | 'approval_prompt' | 'quote' | 'list' | 'refusal', required: What filming this moment shows: `widget_render`, `approval_prompt`, `quote`, `list` or `refusal`.
      - `why` string, required: Why the moment earns its rank. Trimmed by the validator: it must contain a non-whitespace character.
      - `evidence` object[], required
        - `kind` 'tool_annotation' | 'output_template_present' | 'route' | 'checkpoint', required
        - `detail` string, required: The receipt a reviewer (or the cut) can check the moment against. Trimmed by the validator: it must contain a non-whitespace character.
      - `legibilityEstimate` string, required: The human estimate of on-screen legibility. Trimmed by the validator: it must contain a non-whitespace character.
      - `setupNeeded` boolean, required
      - `risk` object, required
        - `spend` boolean, required
        - `destructive` boolean, 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`: The named project or source does not exist or is owned by another account.
- `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)
