Skip to content

Findings and triage

The organisation-wide findings list, the triage states and justifications a person can record, custom scores, bulk actions, and the VEX each decision writes.

Updated 02 Nov 2026Checked against vdb-site@1a06d67, website@ad775f3

The findings list (/resolve/findings, labelled What to fix first in the console) is every finding your organisation owns, across all repositories, scans and SBOM uploads. It is deduplicated: one row per repository, package and finding id, showing the latest scan’s copy.

Listing findings

GET /v1/findings returns entries and pagination.

Parameter Values Effect
page, perPage integers; perPage default 50, maximum 200 Paging
q text Searches titles, ids, packages and CWE ids
sev critical, high, medium, low, unknown Severity band
filter open, resolved, notAffected, falsePositive, reachable, fixable, unfixable, exploitable, malware, eol, aged, detectionBlind, suppressed, testCode One metric bucket. All but resolved, notAffected, falsePositive and suppressed also require the finding to be open.
states comma list of open, resolved, notAffected, suppressed Analysis states to include. notAffected includes false_positive.
cwe CWE id Weakness filter
includeSuppressed true Suppressed findings are hidden unless this is set, states contains suppressed, or filter=suppressed
sort priority, prediction Default is severity score, then title. priority orders by the risk strategy tier, oldest first within a tier. prediction orders by the effective exploit prediction.

GET /v1/findings/metrics returns the counts behind the bucket chips: total, reachable, fixable, unfixable, notAffected, falsePositive, resolved, exploitable, malware, eol, aged, detectionBlind, testCode, orgScored, consumed, untriaged, suppressed, all.

Triage states

A triage records an analysis state, and for some states a justification and responses. The console’s triage dialog offers the five states with a console label; the API accepts all ten. suppressed is meant to be written by a suppression; the API does not refuse it from a person, but a triage of suppressed creates no rule, so the next scan’s copy is not hidden.

analysisState In the console VEX status written Needs a justification
in_triage In Triage under_investigation no
under_investigation under_investigation no
exploitable Exploitable affected no
affected affected no
not_affected Not Affected not_affected yes
false_positive False Positive not_affected yes
resolved Resolved fixed no
fixed fixed no
resolved_with_pedigree fixed no
suppressed not offered not_affected no; normally written by a suppression

Any other value is 400 invalid analysisState. A not_affected or false_positive without analysisJustification is 400 justification is required for not_affected / false_positive.

The console offers these justifications (analysisJustification): code_not_present, code_not_reachable, requires_configuration, requires_dependency, requires_environment, protected_by_compiler, protected_at_runtime, protected_at_perimeter, protected_by_mitigating_control. And these responses (analysisResponse, a list): can_not_fix, will_not_fix, update, rollback, workaround_available. analysisDetail is free text.

Recording a triage

curl -sS -X PATCH "https://www.vulnetix.com/api/site/v1/findings/$FINDING_UUID/triage" \
  -H "Authorization: ApiKey $VULNETIX_ORG_ID:$VULNETIX_API_KEY" \
  -H 'Content-Type: application/json' \
  -d '{"analysisState":"not_affected","analysisJustification":"code_not_reachable","analysisDetail":"The vulnerable parser is never called."}'

The body may also carry a custom score (below). A finding of another organisation is 404 not found.

What one triage writes, in one transaction:

  1. The finding’s latest Triage row, with you as its author (memberUuid).
  2. The finding-scoped VEX: a statement for this vulnerability in your organisation’s OpenVEX document (its version goes up by one) and a VexAnalysis row.
  3. For false_positive only: a suppression rule anchored on the finding’s rule id, category, repository and package (or file, for SAST-family findings), unless an active rule already covers it. The next scan’s copy of the finding stays suppressed. See Suppressions.

Custom scores

An analyst can override the vendor score on a finding with a CVSS vector and score (0 to 10) and a CWSS vector and score (0 to 100). The risk strategy metrics CUSTOM_CVSS and CUSTOM_CWSS read these, and CVSS and CWSS prefer them over the vendor’s.

PATCH /v1/findings/{uuid}/score with cvssVector, cvssScore, cwssVector, cwssScore, any of which may be empty. A score outside its range is 400. A recast stamps you on the latest Triage row but does not set its triage date, so scoring a finding does not take it out of the Awaiting Review triage lane. It mints a VEX statement with status under_investigation and detail “custom score recast”.

Bulk actions

Each bulk route takes findingUuids and applies the change to each finding in its own transaction, so one failure does not undo the rest.

Route Body Response
POST /v1/findings/bulk/triage findingUuids plus the triage fields {success, failed, errors}
POST /v1/findings/bulk/score findingUuids, cvssVector, cvssScore, cwssVector, cwssScore {success, failed}
POST /v1/findings/bulk/suppress findingUuids, suppressionType (required), reason, ignoreDays {success, failed}

A finding that is not yours counts as failed; it is not an error for the request.

Awaiting review

/resolve/awaiting-review collects what is waiting on a person: untriaged findings, suppressions with no review date and VEX-sourced suppressions pending approval, dependency decisions and Pix call reviews. Its actions reuse the routes on this page and on Suppressions. The Reviewers tab of /resolve/logs is the register of who decided what.

Route Returns
GET /v1/review/counts Counts per lane, including suppression and suppressionPending
GET /v1/review/findings Findings waiting for triage
GET /v1/review/decisions Decisions already made
GET /v1/review/audit, GET /v1/review/audit/summary The decision register
Edit this pageSources: vdb-site/api/internal/handler/finding_triage.go, vdb-site/api/internal/handler/findings.go, vdb-site/api/internal/handler/findings_query.go, vdb-site/api/internal/handler/github_alert_writeback.go, vdb-site/api/main.go, website/src/components/findings/TriageDialog.vue
esc
↑ ↓ move↵ openSearches in your browser. A key like autonomy.max or a code like threshold_required jumps straight to it.