Vulnerabilities API
HTTP reference for listing findings, state transitions, bulk updates, comments, evidence files, history, summary, quality gates and export.
All paths are relative to https://api.aleex-rank.ai/api/v2 and authenticate with X-API-Key: rk_... (see REST API). Findings hang off a pentest, so most paths begin with /pentests/{id}/vulnerabilities. For the lifecycle model — states, severity, SLAs and evidence — read Vulnerabilities.
List vulnerabilities
GET /pentests/{id}/vulnerabilities
Returns the findings for a pentest. Supports page and per_page, and can be filtered by status, severity and priority.
{
"success": true,
"data": {
"items": [
{
"id": 42,
"title": "Reflected XSS in search",
"severity": "high",
"status": "open",
"priority": "normal",
"due_date": "2026-02-17 14:30:00",
"assigned_to": null,
"created_at": "2026-02-10 14:30:00"
}
],
"pagination": {"total": 1, "count": 1, "per_page": 20, "current_page": 1, "total_pages": 1}
}
}
Retrieve, update, delete
GET /pentests/{id}/vulnerabilities/{vulnId}
PATCH /pentests/{id}/vulnerabilities/{vulnId}
DELETE /pentests/{id}/vulnerabilities/{vulnId}
GET returns the full finding. PATCH updates editable fields. DELETE removes it.
State transitions
A finding is always open, in_progress, resolved, false_positive or accepted_risk. The dedicated endpoints below carry the extra data each transition needs; the generic status endpoint only moves a finding to open or in_progress.
Resolve
POST /pentests/{id}/vulnerabilities/{vulnId}/resolve
{
"resolution_type": "evidenced",
"comment": "Upgraded nginx and added output encoding"
}
resolution_type is evidenced (requires at least one uploaded evidence file, else 400) or without_evidence.
Reopen
POST /pentests/{id}/vulnerabilities/{vulnId}/reopen
Sends a closed finding back to open and recomputes its due date. Reopening a false positive clears the stored reason.
False positive
POST /pentests/{id}/vulnerabilities/{vulnId}/false-positive
{
"reason": "Endpoint is behind authentication and not externally reachable",
"comment": "Confirmed with the infrastructure team"
}
reason is required (max 2000 characters).
Accept risk
POST /pentests/{id}/vulnerabilities/{vulnId}/accept-risk
{"reason": "Accepted for this release; tracked in RISK-128"}
Generic status and priority
PATCH /pentests/{id}/vulnerabilities/{vulnId}/status
PATCH /pentests/{id}/vulnerabilities/{vulnId}/priority
{"status": "in_progress"}
{"priority": "urgent"}
The status endpoint accepts only open and in_progress. Use the dedicated endpoints above for resolved, false_positive and accepted_risk.
Assignment
POST /pentests/{id}/vulnerabilities/{vulnId}/assign
DELETE /pentests/{id}/vulnerabilities/{vulnId}/assign
The pentest must belong to a team and the assignee must be a member of it. Assigning an open finding moves it to in_progress automatically and emails the assignee.
{"user_id": 42, "comment": "Please verify the patch"}
DELETE …/assign unassigns (no body).
Comments
GET /pentests/{id}/vulnerabilities/{vulnId}/comments
POST /pentests/{id}/vulnerabilities/{vulnId}/comments
PATCH /pentests/{id}/vulnerabilities/{vulnId}/comments/{commentId}
DELETE /pentests/{id}/vulnerabilities/{vulnId}/comments/{commentId}
GET returns a combined feed of user comments and automatic system entries. Filter with ?type=comment, ?type=status_change or ?type=assignment. You may only edit and delete your own comment entries (max 5000 characters).
{"comment": "Verified the fix is deployed to production"}
Evidence files
POST /pentests/{id}/vulnerabilities/{vulnId}/evidence-files
GET /pentests/{id}/vulnerabilities/{vulnId}/evidence-files
GET /pentests/{id}/vulnerabilities/{vulnId}/evidence-files/{fileId}
DELETE /pentests/{id}/vulnerabilities/{vulnId}/evidence-files/{fileId}
Upload up to 20 files per finding, each up to 10 MB, of type jpg, jpeg, png, gif, webp, pdf, txt or csv. Each file is validated by extension, declared MIME type and actual content. Upload as multipart/form-data with files[], or as base64 JSON:
{
"files": [
{"name": "patch-proof.png", "data": "data:image/png;base64,iVBORw0KGgo..."}
]
}
Fetching a file returns a time-limited signed download URL:
{
"id": 1,
"vulnerability_id": 42,
"file_name": "patch-proof.png",
"file_type": "image/png",
"file_size": 245760,
"download_url": "https://storage.googleapis.com/...",
"created_at": "2026-02-10 12:00:00"
}
GET /pentests/{id}/vulnerabilities/{vulnId}/evidence (singular) returns the original discovery evidence the agents produced, distinct from resolution evidence files.
History
GET /pentests/{id}/vulnerabilities/{vulnId}/history
An immutable audit trail of every status change.
{
"success": true,
"data": {
"history": [
{
"id": 3,
"changed_by": 1,
"old_status": "false_positive",
"new_status": "open",
"reason": "Confirmed the issue is real after retest",
"created_at": "2026-02-10 14:30:00"
}
],
"total": 1,
"page": 1,
"per_page": 50
}
}
Bulk status update
PATCH /pentests/{id}/vulnerabilities/bulk-status
Update many findings in one transaction — ideal for pipeline triage. Up to 100 ids, transitions limited to open and in_progress. Findings that can’t transition are skipped, not failed.
{
"vulnerability_ids": [1, 2, 3, 5, 8],
"status": "in_progress",
"comment": "Triaging after scan v2.4.1",
"reason": "Pipeline automated triage"
}
{
"success": true,
"data": {
"message": "5 vulnerability(ies) updated",
"updated": 5,
"skipped": 0,
"total_requested": 5,
"errors": []
}
}
Summary
GET /pentests/{id}/vulnerabilities/summary
A rollup for dashboards and gates. The summary object is returned directly inside data.
{
"total": 45,
"by_status": {"open": 12, "in_progress": 8, "resolved": 20, "false_positive": 3, "accepted_risk": 2},
"by_severity": {"critical": 2, "high": 10, "medium": 18, "low": 15, "info": 0},
"by_priority": {"urgent": 3, "high": 7, "normal": 30, "low": 5},
"resolution_rate": 0.556,
"mean_time_to_resolve_hours": 48.3,
"overdue_count": 4
}
A global summary across all your pentests is available at GET /vulnerabilities/summary.
Quality gate
POST /pentests/{id}/vulnerabilities/quality-gate
Evaluate pass/fail rules against the current findings — use it to block a deploy.
{
"rules": [
{"severity": "critical", "max_open": 0},
{"severity": "high", "max_open": 5},
{"min_resolution_rate": 0.8},
{"max_overdue": 0}
]
}
{
"passed": false,
"failures": [
{"rule": "critical max_open 0", "actual": 2, "expected": 0}
]
}
Supported rule types: severity + max_open, min_resolution_rate (0–1), and max_overdue.
Export
GET /pentests/{id}/vulnerabilities/export?format=csv
GET /pentests/{id}/vulnerabilities/export?format=json
Download every finding for a pentest. CSV responses include a Content-Disposition: attachment header. Fields include id, title, description, severity, status, priority, assigned_to, resolution_type, false_positive_reason, due_date, created_at, resolved_at and resolved_by.
Availability
Bulk status, quality gate and webhooks are gated by tier. Assignment to team members requires a team plan; individual Ultra accounts have full triage but no team assignment. See Teams & tiers. To get notified when findings change, see Webhooks.