API Reference · Your Data

Your Vulnerabilities

EdgeProtect findings across your current attack surface — the latest scan of every target, flattened into one collection, worst first. Each finding carries its instance count, so one row answers both "what is wrong" and "how widespread is it".

This is the live view. To read findings inside one specific (immutable) scan instead, use the vulnerabilities section of GET /my/scans/{scan_id}.

GET
/v1/my/vulnerabilities

Cost: 1 credit per successful call · Scope: api:org

Query parameters

severitystringoptional

Only findings of this severity: critical, high, medium, low or info. Unknown values are a 400, not an empty page.

min_cvssnumberoptional

Only findings with a CVSS score at or above this value, 010. Note the scanner does not currently populate cvss_score on most findings — filter on severity instead (see below).

kev_onlybooleanoptional

true to return only findings whose CVE is in the CISA KEV catalogue.

has_cvebooleanoptional

true to return only findings linked to a CVE (many scanner findings — e.g. configuration issues — have none).

limitintegeroptional

Page size, 1–200. Default 50. Out-of-range is a 400, not a silent clamp.

cursorstringoptional

Opaque pagination cursor from a previous page's next_cursor. Replay the same filters with it.

Request

curl "https://api.precursorintelligence.com/functions/v1/my/vulnerabilities?severity=high" \
  -H "Authorization: Bearer $PRECURSOR_API_KEY"

Response

200 OK
{
  "data": {
    "count": 1,
    "items": [
      {
        "id": "3f0a1c9e-8f2b-4a67-9c31-5d7e2b8a4f10",
        "title": "Outdated OpenSSH server",
        "severity": "high",
        "severity_rank": 4,
        "cve_id": "CVE-2025-26465",
        "cwe_id": "CWE-390",
        "cvss_score": null,
        "epss_score": 0.18345,
        "kev_status": false,
        "public_exploit_available": true,
        "status": "open",
        "affected_component": "bastion.acmecorp.com:22",
        "last_verified": "2026-08-06T02:40:33+00:00",
        "scan_id": "f63285e2-9c78-4020-b2bb-5c8bd2ca51ed",
        "instances": 3
      }
    ],
    "next_cursor": "eyJrIjogIjQi...",
    "has_more": true,
    "generated_at": "2026-08-19T09:30:00+00:00"
  },
  "meta": {
    "request_id": "8b16efb8-9a6c-4ace-b817-11cbee626d08",
    "api_version": "1.3.0",
    "credits": { "charged": 1, "remaining": 9998 }
  }
}

Response fields

data.items[].idstring (uuid)optional

The finding id — stable across pages, and the pagination tiebreaker.

data.items[].severity_rankinteger | nulloptional

The sort key behind severity: 5 critical, 4 high, 3 medium, 2 low, 1 info.

data.items[].instancesintegeroptional

How many places this finding was observed (one finding on twelve hosts is one row with instances: 12).

data.items[].scan_idstring (uuid)optional

The scan the finding came from. Use it with GET /my/scans/{scan_id} for full context.

data.next_cursorstring | nulloptional

Follow until null, replaying the same filters. Opaque — do not parse it.

Ordered by severity, not CVSS

The scanner does not currently emit cvss_score on findings, so the collection is ordered by severity — the one field populated on every row. epss_score and cve_id are returned where known so you can re-rank a page client-side. For the same reason, min_cvss and kev_only will match nothing until the scanner starts populating those fields — an empty result there is data reality, not an error.

Errors

StatuserrorWhen
400invalid_severity, invalid_min_cvss, invalid_limit, invalid_cursorA parameter failed validation. Free — rejected before billing.
401invalid_authorizationMissing or malformed Authorization header.
401unauthorizedInvalid/revoked key, IP not allowlisted, or the key lacks the api:org scope.
402insufficient_creditsOrganisation credit balance is below 1.
405method_not_allowedOnly GET and OPTIONS are accepted.
500internalUnexpected server error (credit auto-refunded).

See Errors for the full error reference.