Skip to content

Smart Audit (beta)

Beta

This endpoint is in beta. The request and response formats may still evolve before general availability. Feedback is welcome at [email protected].

Smart Audit turns a list of raw, free-form software strings into vulnerabilities. Unlike audit/software — which expects already structured input (vendor/product/version or a CPE) — Smart Audit accepts messy strings such as "Adobe Reader 5.3" or "nginx 1.14 on windows". The Vulners matcher automatically determines the correct CPE / PURL for each string, which is then fed into the same audit engine as audit/software to return the matched vulnerabilities.

Matching currently runs against the full CPE catalog — the NVD CVE Dictionary plus Vulners custom-built CPEs (extra coverage for OS packages, language libraries and niche vendors) — with PURL-based matching on the way (resolved PURLs are already returned in the response). Catalog behaviour may still evolve while the endpoint is in beta.

POST /api/v4/audit/smart

Auth: X-Api-Key header required. Billed per submitted string.

Python SDK v4

Python examples use the v4 sync client: from vulners import Vulners, then v = Vulners(api_key="YOUR_API_KEY_HERE"). The method has an identical awaitable mirror on AsyncVulners (await v.audit.smart(...)). See the Python SDK page for details.

Parameters

Name In Type Required Description
software body array[string] yes Raw software description strings. 1–500 items, each 1–512 characters. Empty strings are rejected.
fields body array[string] no Same value set as audit/software. Without it the endpoint reports ai_score alone, which cannot express KEV and tops out below the high band. See Enrichment.
cvelistMetrics body boolean no The other spelling of fields: ["cvelistMetrics"].

Batching & rate limits

  • Hard limits: 1–500 strings per request, each 1–512 characters.
  • Recommended batch size: ≤128 strings per request. Larger batches are accepted up to the hard limit, but smaller batches keep latency stable and make retries cheaper.
  • HTTP 429 (Too Many Requests): retry with exponential backoff and honor the Retry-After response header when present — wait at least that many seconds before retrying.

Response schema

The response is an object with a single result key holding one entry per submitted string (order preserved):

Field Type Description
input string Echo of the submitted raw string.
cpe string CPE 2.3 the string resolved to (version included). Empty string if the matcher found no CPE.
purls array[string] Package URLs (pURL) the matcher associated with the string. Informational; not used for matching in this version.
confidence number Matcher construct confidence, 0.0–1.0.
fixedVersion string Version to upgrade to so that none of the listed advisories still applies. Empty when no matched criterion bounds the affected range from above.
vulnerabilities array[object] Matched vulnerabilities (same shape as audit/software). Empty if no matches or unresolved.

Each item in vulnerabilities carries id and reasons, plus a default set of advisory fields (title, short_description, type, href, published, modified, ai_score). Ask for fields to get metrics, exploitation and cvelistMetrics as well — the same enrichment audit/software returns, in the same shape. The reasons[] structure is identical to audit/software.

Order the findings by ssvc, not by score

With cvelistMetrics requested, every entry carries ssvc — the CISA decision on that CVE. It matters here more than anywhere else: a single software string can resolve to over a thousand advisories, several hundred of them scoring 7 or above, which is not a queue anyone can work.

Sort on the Exploitation axis — activepocnone — and fall back to CVSS within a tier. It is reported for effectively every CVE: on Google Chrome 149.0.7827.89, 1 457 of 1 466 entries carried it. The KEV flag on exploitation.wildExploited marked exactly one.

See Enrichment for the full entry shape.

One item comes back per submitted string, in request order, including strings that resolved to nothing — so the response is always the same length as the request. Join on input anyway: it costs nothing and survives the ordering ever changing.

Catalog

Smart Audit always resolves against the extended CPE catalog (NVD plus Vulners entries), because it works with raw strings and the official catalog is NVD only. audit/software defaults to the official one. The catalog governs which CPE name an input resolves to, not which advisories a resolved CPE matches: given the same CPE both endpoints answer with the same advisory set. Feed the cpe reported here to audit/software to compare like with like.

Resilience: transparent fallback

If the matcher service is unavailable, Smart Audit transparently falls back to fuzzy CPE naming (FFN) so a result is still returned — version-agnostic and lower precision. The response shape is unchanged; the incident is recorded server-side (logs + Sentry), not surfaced in the response.

Usage

Query:

POST /api/v4/audit/smart

curl -X POST https://vulners.com/api/v4/audit/smart \
  -H "X-Api-Key: YOUR_API_KEY" \
  -H "Content-Type: application/json" \
  -d '{
    "software": [
      "Adobe Reader 5.3",
      "nginx 1.14 on windows",
      "OpenSSL 1.0.1"
    ]
  }'
# Billed per submitted string — keep batches small.
# The SDK validates the 1-500 items / 1-512 characters limits client-side.
results = v.audit.smart([
    "Adobe Reader 5.3",
    "nginx 1.14 on windows",
    "OpenSSL 1.0.1",
])
for entry in results:
    print(entry["input"], "->", entry["cpe"], len(entry["vulnerabilities"]), "vulnerabilities")
{
  "result": [
    {
      "input": "Adobe Reader 5.3",
      "cpe": "cpe:2.3:a:adobe:acrobat_reader:5.3:*:*:*:*:*:*:*",
      "purls": [],
      "confidence": 0.81,
      "vulnerabilities": [
        {
          "id": "CVE-2020-0001",
          "reasons": [
            {
              "config": "nvd",
              "criterias": [
                [
                  {
                    "criteria": "cpe:2.3:a:adobe:acrobat_reader:5.3:*:*:*:*:*:*:*",
                    "vulnerable": true
                  }
                ]
              ]
            }
          ],
          "title": "...",
          "short_description": "...",
          "type": "cve",
          "href": "https://vulners.com/cve/CVE-2020-0001",
          "published": "2020-01-01T00:00:00",
          "modified": "2020-01-02T00:00:00",
          "ai_score": { "value": 7.5, "uncertainty": 0.5 }
        }
      ]
    },
    {
      "input": "nginx 1.14 on windows",
      "cpe": "cpe:2.3:a:f5:nginx:1.14:*:*:*:*:windows:*:*",
      "purls": [],
      "confidence": 0.77,
      "vulnerabilities": []
    }
  ]
}

Errors

Status Meaning
401 Missing or invalid X-Api-Key.
400 Validation error — empty list, more than 500 items, an empty/over-long string, or an unknown request key.
402 Insufficient wallet balance for the request (restricted licenses).
429 Rate limit exceeded — retry with exponential backoff, honoring Retry-After. See Batching & rate limits.