Security · 4 min

Real-Time CVE Monitoring with the NVD API

How to consume the NIST National Vulnerability Database in real time, filter to your stack, score by CVSS + EPSS exploitability, and route to the right Slack channel. Practical free starter.

2026-05-26

NIST publishes every new CVE in the National Vulnerability Database within hours of MITRE assignment. The data is free, the API is documented, the rate limits are generous. The catch is the same as every other OSINT firehose: 25,000+ CVEs per year means you'd burn out the security channel by week two without the right filter pattern.

This post lays out a practical CVE monitoring stack — NVD + EPSS + KEV — and how to wire it into a security team's workflow without flooding Slack.

The three feeds that matter

NVD (National Vulnerability Database)

Full CVE record with CVSS scores, affected products (via CPE), references, exploit links:

https://services.nvd.nist.gov/rest/json/cves/2.0?lastModStartDate=...&lastModEndDate=...

Rate-limited to 5 requests/30s without a key, 50/30s with a free key. Poll every 30 minutes is fine.

EPSS (Exploit Prediction Scoring System)

FIRST.org's daily-updated probability that a CVE will be exploited in the next 30 days (0.00 to 1.00):

https://api.first.org/data/v1/epss?cve=CVE-2024-1234

EPSS is the single most useful CVE enrichment. CVSS tells you "how bad is the vulnerability"; EPSS tells you "how likely is it that someone is actually exploiting this right now."

CISA KEV (Known Exploited Vulnerabilities)

CISA's curated list of CVEs known to be actively exploited in the wild:

https://www.cisa.gov/sites/default/files/feeds/known_exploited_vulnerabilities.json

Tiny list (~1000 entries) but every entry is a "patch right now" priority.

Severity scoring

Combine the three into a 0-100 score:

function cveSeverity(cve: NvdCve, epss: number, kev: boolean): number {
  if (kev) return 100;                         // KEV = always max
  const cvss = cve.metrics?.cvssV3?.baseScore ?? 0;  // 0-10
  const epssBoost = epss * 30;                 // 0-30
  return Math.round(Math.min(100, cvss * 7 + epssBoost));
}
  • CVSS 9.8 + KEV listed → 100 (drop everything, patch)
  • CVSS 9.8 + EPSS 0.05 → 70 (high CVSS but no active exploitation, schedule patch)
  • CVSS 5.4 + EPSS 0.85 → 60 (moderate CVSS but actively exploited, prioritise)
  • CVSS 9.8 + EPSS 0.01 → 68 (high CVSS but no exploitation signal)

EPSS reorders the priority list dramatically. Most teams ignore EPSS and pay for it by patching the wrong CVEs first.

Filtering to your stack

NVD is huge. To make it usable, filter on CPE (Common Platform Enumeration) — the structured way to say "this vulnerability affects Apache HTTP Server 2.4.x." Build a CPE allow-list from your software inventory:

cpe:2.3:a:apache:http_server:2.4.*
cpe:2.3:a:openssl:openssl:1.1.*
cpe:2.3:o:linux:linux_kernel:5.*
...

NVD's CPE filter is part of the query:

https://services.nvd.nist.gov/rest/json/cves/2.0?cpeName=cpe:2.3:a:apache:http_server:2.4.55

If you maintain a 50-200 entry CPE allow-list, you'll drop 95% of NVD volume on day one.

Routing patterns

Three patterns that scale:

Severity-tiered Slack channels:

  • ≥80 → #sec-critical (page on-call)
  • 60-79 → #sec-high (review within 24h)
  • 40-59 → #sec-medium (weekly digest)
  • under 40 → log to security audit only

Per-team CPE routing:

  • Web team gets CVEs matching their stack
  • Infrastructure team gets OS / hypervisor CVEs
  • Mobile team gets iOS / Android library CVEs

Auto-ticket creation:

  • KEV-listed CVE → auto-create Jira / Linear / GitHub issue
  • ≥CVSS 9.0 → auto-assign to security on-call

False-positive reductions

NVD has a few known noise patterns to filter:

  1. Disputed CVEs: filter out cveStatus = Disputed. These are CVEs the vendor disputes the validity of — usually noise.
  2. Rejected CVEs: filter cveStatus = Rejected. Same thing.
  3. Vendor-acknowledged-only: consider downweighting CVEs without a CVSS v3 score — those are usually low-quality.

Free starter stack

Minimum viable CVE monitoring this week:

  1. Register a free NVD API key
  2. Build CPE allow-list from your asset inventory
  3. Poll NVD every 30 minutes filtered by your CPEs
  4. Cross-reference each new CVE against EPSS (daily refresh)
  5. Cross-reference against KEV (daily refresh)
  6. Score on 0-100 → severity-tiered Slack routing

Augur's NVD ingest wraps the CPE filtering + EPSS + KEV cross-reference + severity scoring with the same dispatcher used for the rest of the platform. The data is free; the pipeline is the work.

When you need more

For dedicated vulnerability-management programs:

  • Tenable / Qualys / Rapid7 — scan-based VM platforms with their own CVE intelligence
  • Snyk / Mend / GitHub Advanced Security — code-level dependency scanning
  • VulnCheck — paid CVE enrichment with exploit code references
  • CISA KEV + their public dashboards — free, government-maintained

For most teams the NVD + EPSS + KEV combination is enough for the first 18 months. After that the prioritisation question shifts from "which CVEs matter" to "which assets are vulnerable" — that's where scan-based VM platforms earn their fee.

What this looks like in production

Mid-market SaaS: 80-entry CPE allow-list + NVD + EPSS + KEV scoring routes ~5 CVEs/week to #sec-high, ~0-2/month to #sec-critical. Replaced a weekly manual review.

European bank: dedicated CPE per service team (200+ entries total). KEV-listed CVEs auto-create Jira tickets. CVSS ≥9 wakes the on-call security engineer.

Open-source maintainer: NVD feed for their own product CPE → posts to their security advisories repo on every new CVE matching the package name.

Public data. Geofencing-equivalent (CPE) is the layer that makes it usable.

← Back to blog · Start free