Findings
Pull findings, filter them, change their status, re-test a fix, and open a fix PR.
A finding is one issue the agent confirmed. Findings come from a run or from a
PR review — exactly one of run_id or pr_review_id is ever set.
The finding object
Prop
Type
Check `locked` before reading detail
On a free trial, a critical or high finding arrives with only id, run_id,
domain_id, severity, status, created_at, and locked: true. The other fields are
absent, not null. Code that reads finding.title unconditionally will break on a trial
organization.
List findings
GET /findings · scope findings:read · role analyst
Every finding in the organization, with a severity breakdown of exactly the list returned.
Prop
Type
Each finding in this response carries one extra field beyond the object above:
Prop
Type
curl "https://api.vulnix.dev/findings?status=open&severity=critical" \
-H "Authorization: Bearer $VULNIX_TOKEN"{
"findings": [],
"severity_breakdown": { "critical": 0, "high": 0, "medium": 0, "low": 0, "info": 0 }
}severity_breakdown always summarizes the list above it, so it reflects your filters rather
than the organization total.
Get a finding
GET /findings/{finding_id} · scope findings:read · role analyst
The finding object plus its re-test history:
Prop
Type
Update a finding
PATCH /findings/{finding_id} · scope findings:write · role analyst
Prop
Type
Exactly one field per request
Send status or accepted_risk, never both and never neither — either mistake returns
422 invalid_finding_update_request. They are independent axes: accepting the risk is not a
status, and a finding whose risk is accepted keeps whatever status it had.
curl -X PATCH https://api.vulnix.dev/findings/$FINDING_ID \
-H "Authorization: Bearer $VULNIX_TOKEN" \
-H "Content-Type: application/json" \
-d '{"status": "fixed"}'Returns the updated finding object. Accepting a risk that is already accepted returns
409 finding_risk_already_accepted.
Re-test a fix
POST /findings/{finding_id}/validate-fix · scope findings:write · role analyst
Re-runs the agent against this one finding to confirm the fix holds. Counts against the run-starting rate budget.
Prop
Type
Returns the new attempt object. A re-test already in flight for this finding returns
409 validate_fix_already_in_progress. Poll GET /findings/{finding_id} and read the first
entry of validate_fix_attempts for the outcome.
Open a fix PR
POST /findings/{finding_id}/create-fix-pr · scope findings:write · role admin
Opens a pull request against the connected repository with the prepared patch. No body. Counts against the run-starting rate budget.
Returns the updated finding object with fix_pr_url populated.
Prop
Type
Export a finding timeline
GET /findings/{finding_id}/timeline/report · scope findings:read · role analyst
A PDF of the finding's full history: detection, then every re-test attempt in order. PDF is the
only format. Returns 403 premium_detail_required for a locked finding.
Dashboard overview
GET /dashboard/overview · scope findings:read · no minimum role
Pre-aggregated security posture — the numbers behind the console's dashboard, so you do not have to compute them from the raw finding list.
Prop
Type
Returns the security score and its delta, open issues, issues found, fix rate, pentest count, a severity breakdown, and the issues-over-time, open-vs-fixed, and MTTR series.
Cached
This response is cached briefly per organization and range, so two calls a second apart can return identical numbers. Poll a run's status for live progress, not this.