---
title: "Advisor brief for a book-scan response"
method: POST
path: "/api/v1/book-scan/brief"
tags: ["book-scan", "narrate"]
---

# Advisor brief for a book-scan response

`POST /api/v1/book-scan/brief`

## Request

- Base URL: `https://worthune.com`
- URL: `https://worthune.com/api/v1/book-scan/brief`
- Auth: one of:
  - HTTP bearer
  - API key in header `X-Api-Key`

A model drafts a short brief from a book-scan RESPONSE; a deterministic gate verifies every number in the prose against the scan (one regeneration, then refusal). Stateless. Any key role. 60/hour per org. The drafting model: x-model-key for the request, else your narrator model (model policy), else ours; the response names it.

## Headers

- `x-model-key` string

## Request body

- object
  - `scan` BookScanResult, required
    - `queue` BookScanOpportunity[], required: Ranked by opportunityUsd, desc.
      - `householdId` integer, required: On the keyless route: the 1-based position in the submitted households array.
      - `label` string, nullable
      - `advisorRef` string, nullable
      - `strategy` string, required
      - `alternativeId` string, required
      - `alternativeLabel` string, required
      - `opportunityUsd` number, required: Top alternative's endingNetWorthDelta vs its own baseline — a triage estimate.
      - `improvesRuin` boolean, required
      - `recordSha256` string, required
    - `advisorRollups` object[], required
      - `advisorRef` string, nullable, required
      - `households` integer, required
      - `opportunities` integer, required
      - `opportunityUsd` number, required
      - `topOpportunityUsd` number, required
      - `improvesRuin` integer, required
    - `skipped` object[], required
      - `householdId` integer, required
      - `strategy` string, required
      - `reason` string, required
    - `householdsScanned` integer, required
    - `householdsTruncated` integer, required: Households beyond the cap that were NOT scanned — never silent.
    - `strategiesRun` string[], required
    - `notes` string[], required

## Response `200`

The verified brief.

- object
  - `ok` unknown, required
  - `narrative` string, required
  - `verification` NarrativeVerification, required
    - `numericClaims` integer, required
    - `verifiedClaims` integer, required
    - `structuralExempt` integer, required
    - `attempts` integer, required: 1, or 2 when the first draft was rejected and regenerated.
    - `gate` 'every numeric claim verified against the source computation', required
    - `recordSha256` string: Present when a stored decision was narrated.
    - `note` string, required
  - `drafter` Drafter, required: Which model drafted. The deterministic gates after it are the same whichever it was.
    - `source` 'caller-key' | 'organization-policy' | 'deployment', required: x-model-key for this request, else your organization's role model (PUT /api/v1/model-policy), else the deployment's.
    - `provider` 'anthropic' | 'gemini' | 'openai-compatible' | 'azure-openai', required
    - `model` string, required

## Other responses

- `400`: Malformed JSON, a body of the wrong shape, or a top-level field that fails its check.
- `401`: No key presented (Authorization: Bearer wk_… or X-Api-Key).
- `402`: Unrecognized or revoked API key.
- `403`: The key predates organization support (contact support for a free rotation).
- `422`: `scan` is not a book-scan response object.
- `429`: Hourly per-org stateful quota, a per-route durable limit, or the 120 requests/minute per-IP burst backstop.
- `502`: The narration model did not answer, or two drafts failed the numeric gate (violations listed).
- `503`: Billing is not configured on this deployment; household resources are disabled rather than served without tenancy (production fail-closed).

---

[API](https://skmtc.dev/worthune/apis/worthune-api.md) · [All operations](https://skmtc.dev/worthune/apis/worthune-api/llms.txt) · [OpenAPI document](https://skmtc.dev/worthune/apis/worthune-api/revisions/9f2241072555?raw)
