---
title: "One finding with its evidence and history"
method: GET
path: "/findings/{findingId}"
tags: ["findings"]
---

# One finding with its evidence and history

`GET /findings/{findingId}`

## Request

- Base URL: `https://shruwd.io/api/v1`
- URL: `https://shruwd.io/api/v1/findings/{findingId}`
- Auth: HTTP bearer

## Response `200`

The finding.

- FindingDetail
  - `findingId` string, required
  - `number` integer, required: 1, 2, 3… per workspace, never reused. The dashboard links by it (/brands/{slug}/findings/{number}) and `{findingId}` accepts it.
  - `ruleId` string, required
  - `family` 'ACCESS' | 'STRUCT' | 'CITE' | 'FACT' | 'COVERAGE', required
  - `severity` 'critical' | 'high' | 'medium' | 'low', required
  - `confidence` 'observed' | 'inferred' | 'heuristic', required: `observed` — measured from first-party data. `inferred` — a reliable pattern. `heuristic` — plausible, unconfirmed; treat as a hypothesis.
  - `state` 'open' | 'acknowledged' | 'fix_applied' | 'rechecking' | 'resolved' | 'not_moved' | 'dismissed' | 'stale', required
  - `subjectType` 'url' | 'prompt_group' | 'domain' | 'brand', required
  - `subjectRef` string, required
  - `evidence` object, required: What the rule saw. Shape depends on `ruleId`.
  - `recommendation` Recommendation, required
    - `summary` string, required
    - `steps` string[], required
    - `target` string, nullable, required: The specific artifact to change: a URL, a file, a setting. Null on a finding about a question when no page of the brand's is cited for it and none is set: the steps say so. Set one with `PATCH /prompts/{promptGroupId}` (`page`); the finding's `subjectRef` is that id.
    - `expectedMetric` string, required: Which metric should move if the fix works.
  - `firstSeenAt` string, date-time, required
  - `lastSeenAt` string, date-time, required
  - `suppressedBy` string, nullable, required: The finding that explains this one, when suppressed.
  - `surfaced` boolean, required: False while the finding waits behind the weekly cap.
  - `estimatedImpact` number, required
  - `brandId` string, required
  - `suppressedByNumber` integer, nullable, required: The `number` of `suppressedBy`, when suppressed.
  - `stateChangedAt` string, date-time, required
  - `baseline` object, nullable, required: The snapshot captured at `fix_applied`, which a recheck verdict is measured against: `{ capturedAt, window: { from, to }, promptGroups: [ { promptGroupId, x, n, modelIds } ] }`. Null before a fix is marked applied.
  - `events` FindingEvent[], required: Newest first.
    - `eventId` string, required
    - `from` string, nullable, required
    - `to` string, required
    - `actor` string, required: A user id, or `system`.
    - `actorName` string, nullable, required: The member's name, else their email, when a person acted. Null for `system`.
    - `note` string, nullable, required
    - `payload` object, nullable, required: What the transition recorded. A recheck verdict (`to` = `resolved` or `not_moved`) carries `results`: one entry per prompt group compared, with `verdict`, `delta`, `baselineInterval`, `afterInterval`, `deltaInterval` (the change's 95% interval) and `deltaExcludesZero`, `p`, both gates, `confounded` and `modelIdDrift` (metrics.md §6). It also carries `pooled`: the same fields for the groups taken together, plus `groups`, or null when fewer than two were compared. `resolved` means the pooled comparison or at least one group moved. Verdicts from 2026-10-01 also carry `outcome`: `worked` (resolved), or for `not_moved` one of `rising` (up 5 points or more, not proven), `no_change`, `fell` (a drop that passed both gates), `confounded` (a model change) or `insufficient` (under 10 answers); with `looks` (rechecks of the fix judged together, at most 2), `followUpAfter` (when a rising first look gets its second, else null), `engines` (the engines judged), `outOfReach` (an engine left out because it answered from memory: `engine`, `answers`, `citingNothing`) and, from 2026-10-15, `notInBaseline` (engines left out because they were not answering the questions through the whole baseline window, such as Google AI Mode for a fix marked applied before it was tracked). Each result then carries the counts it compared: `baselineX`, `baselineN`, `afterX`, `afterN`. A structural confirmation carries `structural`: what the check saw.
    - `at` string, date-time, required

## Other responses

- `403`: `not_entitled`: the plan shows only its first `maxVisibleFindings` findings in full and this is not one of them — it is counted in a findings list's `locked`. `details` carries `plan`, `resource` and `limit`.
- `404`: `not_found`: no such resource in this workspace.
- `default`: Every failure has this body.

---

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