---
title: "Code Scan Summary"
method: GET
path: "/v1/projects/{project_id}/code-scan/summary"
tags: ["code-scan"]
---

# Code Scan Summary

`GET /v1/projects/{project_id}/code-scan/summary`

## Request

- Base URL: `https://api.sonenta.dev`
- URL: `https://api.sonenta.dev/v1/projects/{project_id}/code-scan/summary`
- Auth: none declared

Current counts per status + the last run.

`measured=False` means NO scan has ever reported a finding here — it does NOT
mean the code is clean. Zero findings from a scanner that never ran is not an
absence of hardcoded strings.

`excluded` reshapes the per-status counts; the top-level `excluded` integer is
the always-on 'Exclusions (N)' badge (findings masked by >=1 rule).

## Path parameters

- `project_id` string, required

## Query parameters

- `excluded` string: Exclusion-rule filter for the per-status counts (default `exclude`): `exclude` hides matched findings · `only` counts ONLY matched · `include` ignores rules. The top-level `excluded` badge total is param-independent.

## Response `200`

Successful Response

- CodeScanSummaryOut
  - `project_uuid` string, required
  - `total` integer, required
  - `new` integer, required
  - `treated` integer, required
  - `gone` integer, required
  - `excluded` integer, required: Findings masked by >=1 exclusion rule (all statuses) — the 'Exclusions (N)' badge. Always the positive union, independent of the `excluded` query param; equals total(include) - total(exclude).
  - `by_category` CodeScanByCategory, required: Category x status. `keyless` = raw literal with no key · `key_default` = a key's defaultValue · `unknown` = everything the scanner did not label as one of those (incl. findings from before the field existed). `keyless.new` is the UI headline: hardcoded strings with no key, still to treat.
    - `keyless` CodeScanStatusCounts, required
      - `new` integer, required
      - `treated` integer, required
      - `gone` integer, required
    - `key_default` CodeScanStatusCounts, required
      - `new` integer, required
      - `treated` integer, required
      - `gone` integer, required
    - `unknown` CodeScanStatusCounts, required
      - `new` integer, required
      - `treated` integer, required
      - `gone` integer, required
  - `last_scan` CodeScanLastRun, required: The last ingest, TYPED — previously `dict | None`, which left the OpenAPI silent and forced the dashboard to ask me what the field contains (a contract that obliges the consumer to ask is not a contract). `scan_id` mirrors `uuid`: the ingest response calls this same identifier `scan_id`, and one entity under two names across two endpoints is how a client bug gets written. `uuid` is kept so existing readers do not break. NOTE for future edits: this model now FILTERS the stored run document. A new field added to `code_scan_runs` is dropped from the response unless it is declared here too.
    - `scan_id` string, required
    - `uuid` string, required: Legacy alias of `scan_id` — prefer `scan_id`.
    - `org_uuid` string, nullable
    - `project_uuid` string, required
    - `created_at` string, date-time, required
    - `submitted` integer, required: How many findings this run posted.
    - `counts` CodeScanRunCounts, required: Per-RUN figures. `persisting` lives here and NOWHERE else: it is not a stored status (those are new/treated/gone), it is what one run observed — "known, still present, not treated". A finding that persists stays `new`, which is why the summary's top-level counts have no `persisting` column.
      - `new` integer, required
      - `persisting` integer, required
      - `treated` integer, required
      - `gone` integer, required
    - `meta` object: Verbatim passthrough of whatever the scanner sent. The backend validates and guarantees NO key here — treat every field, and the object itself, as optional.
    - `via` string, required: Which surface ingested it: `core` or `mcp`.
    - `confirm_mass_gone` boolean
    - `recorded_by_user_uuid` string, nullable
    - `recorded_by_api_key_uuid` string, nullable
  - `measured` boolean, required
  - `formula` object, required

## Other responses

- `422`: Validation Error

---

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