# NVD CVE Scraper — Vulnerabilities by Product, Severity & KEV (`northbell/nvd-cve-scraper`) Actor

CVE vulnerabilities from the official NIST NVD API 2.0: description, CVSS v3.1 / v4 score, CWE, affected vendor and product, CISA KEV fields. Filter by product, keyword, severity or KEV, and flag CVEs that are new or changed since your last run.

- **URL**: https://apify.com/northbell/nvd-cve-scraper.md
- **Developed by:** [Northbell](https://apify.com/northbell) (community)
- **Categories:** Developer tools, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.60 / 1,000 cves

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## NVD CVE Scraper — Vulnerabilities by Product, Severity & KEV

Search the **NIST National Vulnerability Database (NVD)** by product, keyword, CVE id, weakness, severity, CISA KEV status or date, and get one clean row per CVE: **English description, CVSS v3.1 and v4 score, severity and vector, CWE ids, affected vendor and product, references, and the CISA Known Exploited Vulnerabilities (KEV) fields**, with a link to the CVE on NVD. **$2.00 per 1,000 CVEs**, no login, no API key needed.

Run it again, or put it on a daily schedule, and every row also tells you **whether the CVE is new since the last run (`isNew`) and whether its record changed (`isChanged`, the NVD `lastModified` moved)**. Set *What to return* to *New or changed* and you pay only for those. In the 7 days up to 16 Oct 2026 NVD published 5,343 CVEs and changed 14,643 records, so the useful question is what moved since yesterday; this keeps the list of what you have already seen.

> This product uses the NVD API but is not endorsed or certified by the NVD.

**Try it now. The input is already filled in.** Press **Start**: every CVE for the product `jetbrains:youtrack` — **100 CVEs in about 10 seconds, for $0.21** (measured on 28 Oct 2026): 6 critical, 23 high, 65 medium, 6 low. Three of the rows:

| `cveId` | `cvssV3Score` | `cvssV3Severity` | `published` | `cweIds` |
| --- | --- | --- | --- | --- |
| CVE-2026-103493 | 8.1 | HIGH | 2026-10-01 | CWE-79 |
| CVE-2026-103490 | 7.2 | HIGH | 2026-10-01 | CWE-862 |
| CVE-2026-103497 | 5.5 | MEDIUM | 2026-10-01 | CWE-918 |

Each row also has the description, CVSS vectors, affected products, references and whether CISA lists it as exploited (`isKev`).

### What you get

| Field | What it is |
|---|---|
| `cveId`, `url` | the CVE id (`CVE-2026-0322`) and its page on nvd.nist.gov |
| `status` | NVD's processing status: `Received`, `Awaiting Analysis`, `Undergoing Analysis`, `Analyzed`, `Modified`, `Deferred`, `Rejected` |
| `published`, `lastModified` | when NVD published the record and when it last changed, in UTC |
| `isNew`, `isChanged`, `previousLastModified`, `previousRunAt` | whether the CVE was not in your previous run of the same search (a CVE older than where that run stopped at its cap is not counted as new; in a KEV search, one added to KEV since then is), whether its `lastModified` moved since then, the earlier `lastModified`, and when that run was (all `null` on the first run) |
| `description` | the English description |
| `cvssV3Score`, `cvssV3Severity`, `cvssV3Vector`, `cvssV3Version`, `cvssV3ScoredBy` | the CVSS v3.1 base score, severity and vector (v3.0 where there is no 3.1), and who scored it: `NVD` (NVD's own analysis) or `other` (the organisation that reported the CVE, or a third party). NVD's own score wins when there are several |
| `cvssV4Score`, `cvssV4Severity`, `cvssV4Vector`, `cvssV4ScoredBy` | the same for CVSS v4.0 |
| `topScore` | the higher of the v3 and v4 base scores (what *Minimum CVSS score* compares) |
| `cweIds` | weakness ids (`CWE-79`, `NVD-CWE-Other`…), each once |
| `affectedProducts`, `affectedProductCount`, `affectedProductsSource` | `{vendor, product}` pairs from the CPE records NVD attaches to the CVE (`cpe`), or, when NVD has not added any yet, the names the reporting organisation gave (`cna`). Up to 100 are listed; the count is complete |
| `references`, `referenceCount` | reference URLs only (up to 50 listed) |
| `isKev`, `kevAddedOn`, `kevDueDate`, `kevRequiredAction`, `kevName` | CISA's KEV catalog entry: the date it was added, the due date for US federal agencies, the required action and CISA's name for the vulnerability (`null` when the CVE is not on the list) |
| `tags` | NVD CVE tags such as `disputed` |
| `observedAt` | when the row was collected |

### Run it again and again

- **On a schedule**: save your input as a task and add a **Schedule**: the same search every morning. Send each run to Google Sheets, Slack or email with an integration on the task.
- **Watch for changes**: Set **What to return** to *New or changed*. A CVE whose record NVD updates, for example when it adds its own analysis, comes back with `isChanged`.
- **In bulk**: Put several products and keywords in one run; the searches are combined and a CVE found twice is returned once.

### Use it for

- **Patch monitoring**: a daily schedule with your products (`apache:http_server`, `microsoft:windows_11_24h2`, `jetbrains:teamcity`), *High* severity and *New or changed*, sent to Slack or a ticket queue
- **KEV watch**: *Only CVEs on the CISA KEV list* with *Modified since* `2 days` shows what was just added or changed on the exploited-in-the-wild list
- **Vendor and supply-chain reports**: every CVE for a vendor or a dependency, with score, weakness and affected products
- **Security research**: CVEs by weakness (`CWE-89`) or keyword over any period, with score and vector for your own analysis

### Input

```json
{
  "products": ["jetbrains:teamcity", "apache:http_server"],
  "severity": "HIGH",
  "modifiedSince": "7 days",
  "maxResults": 100,
  "output": "new-or-changed"
}
```

- Filters are combined with AND. Several lines in *Vendor / product* and *Keywords* are searched one after the other and combined (OR), up to 50 searches (keywords × products) per run.
- **products**: `vendor:product` as NVD spells it in its CPE names (lower case, underscores for spaces): `apache:http_server`, `jetbrains:youtrack`. A vendor alone (`jetbrains`) works. A full CPE 2.3 name works too: with a version (`cpe:2.3:a:apache:http_server:2.4.58`) it matches that version, without one it matches every version.
- **keywords**: words that must all appear in the description (not necessarily together). Tick *exact phrase* to require the whole line as a phrase.
- **cveIds**: look up up to 100 CVEs directly. **cweId** — one weakness, for example `CWE-79`.
- **severity**: `LOW` to `CRITICAL`. With CVSS v3 it is sent to NVD, which needs a v3 score on the CVE; with CVSS v4 it is checked on the rows (see Notes).
- **minScore**: the highest of the v3 and v4 base scores must be at least this. CVEs with no score are left out. Checked after reading, so CVEs that miss it are not charged.
- **publishedSince / publishedUntil / modifiedSince / modifiedUntil**: a date (`2026-10-01`), a date and time in UTC (`2026-10-01T08:00:00`) or a relative value (`7 days`, `12 hours`). NVD accepts at most 120 days per request; the Actor cuts a longer period into pieces itself. If you set no filter at all, the last 7 days of published CVEs are returned.
- **maxResults** (default 100, up to 5,000) — results are read from the newest end. With *Minimum CVSS score*, a v4 severity or *New / New or changed*, the Actor reads past CVEs that do not qualify (up to 5,000 deep) until it has found that many.
- **apiKey** (optional) — your own free key from [nvd.nist.gov/developers/request-an-api-key](https://nvd.nist.gov/developers/request-an-api-key). See *Rate limits*.

"Is it new or changed" is remembered per search — the same products, keywords, CVE ids, weakness, severity, minimum score, KEV flag and rejected-setting — in a named key-value store in your Apify account, so the second run of the same search already shows `isNew` and `isChanged`. Changing the period or *Maximum CVEs* keeps the same history. A CVE is remembered only if it matched your filters.

### Rate limits

NVD allows **5 requests per 30 seconds without a key and 50 with one**, and its documentation recommends pausing about six seconds between requests. The Actor waits 6.5 seconds between requests without a key and 0.7 seconds with one. NVD counts the limit per IP address, and runs on Apify's servers may share IP addresses with other users, so a run without a key may be refused more often than the numbers suggest: when NVD answers 403 or 429 the Actor waits and retries twice, then adds a free error row and stops. Add your own NVD API key to avoid this. The key is sent to NVD in a request header only; the Actor never writes it to the log, the dataset or the run summary. Use only your own key — NVD's terms do not allow sharing keys.

In a run on 16 Oct 2026 from a desktop PC (no key), reading the 500 newest CVEs took 27 seconds and 2 requests; a keyword search returning 5 CVEs took 10 seconds. I have not measured runs on the Apify platform.

### Pricing

**$2.00 per 1,000 CVEs**, plus $0.01 per run. Error rows (a search NVD rejects, NVD not answering) are free. With *New* or *New or changed*, CVEs you have already seen are skipped and not charged; so are CVEs below your minimum score. The $0.01 run-start fee is the one charge every run pays, even one that returns nothing.

### Notes

- Source: the NVD CVE API 2.0 (`services.nvd.nist.gov/rest/json/cves/2.0`), public data from NIST, used under NVD's [terms of use](https://nvd.nist.gov/developers/terms-of-use). This product uses the NVD API but is not endorsed or certified by the NVD.
- The newest CVEs have no NVD analysis yet. In a read of the 500 newest CVEs on 16 Oct 2026, all 500 were still `Received`, `Deferred` or `Awaiting Analysis` (397 / 68 / 35); none of them had a score from NVD itself. 439 had a CVSS v3 score and 191 a v4 score, all given by the reporting organisation (`cvssV3ScoredBy: other`), and 28 had no score at all. Filtering on severity or score therefore works on whoever scored the CVE; check `cvssV3ScoredBy` if you only trust NVD's analysis.
- Affected products for new CVEs are the reporting organisation's own names: 489 of those 500 CVEs listed them (`affectedProductsSource: cna`), none had CPE records yet, and 11 named no product. NVD adds the CPE records when it analyses the CVE, so the same CVE can change from `cna` to `cpe` names a few days later (and show `isChanged`). Product searches use NVD's CPE records, so a brand-new CVE for a product may only appear in a *keyword* search until NVD has analysed it.
- CVSS v4 is still rare in the NVD filter: on 16 Oct 2026 NVD's own `cvssV4Severity` filter returned 5 CVEs for HIGH and none for CRITICAL, although two CVEs published on 14 Oct carry a CRITICAL v4 score from their reporter. The Actor therefore checks a v4 severity on the rows it reads instead of asking NVD.
- Results come from NVD ordered by publication date, oldest first; the Actor reads from the newest end, so a period with more CVEs than *Maximum CVEs* gives you the newest ones. A record modified long after publication therefore sorts by its publication date, not its modification date.
- The CISA KEV list held 1,746 CVEs on 16 Oct 2026 according to NVD's `hasKev` filter; 167 of them had their record last modified in the 30 days before.
- Descriptions are NVD's English text with any e-mail address removed. No contact persons or reporter names are returned; the Actor does not read NVD's credits.
- `topScore` and `minScore` look at the v3 and v4 base scores only, not at CVSS v2.
- Rejected CVE records are left out unless you untick *Leave out rejected CVEs*.

### For AI agents

`{"products": ["jetbrains:teamcity"], "severity": "HIGH", "maxResults": 5}` returns up to 5 rows, newest first, each with `cveId`, `description`, `cvssV3Score`, `cweIds`, `affectedProducts`, `isKev`. Rows have `type`: `cve` or `error`. Fields that do not apply to a CVE are `null` (or an empty list), never missing. Schedule the same input daily with `"output": "new-or-changed"` to get only what appeared or changed since the previous run. Give a key as `"apiKey"` to raise NVD's rate limit.

# Actor input Schema

## `products` (type: `array`):

Only CVEs that affect these products, one per line. Write vendor:product as NVD spells it in CPE names (lower case, underscores for spaces), for example apache:http_server, microsoft:windows_11_24h2 or jetbrains:youtrack, or just a vendor such as jetbrains. A full CPE 2.3 name also works, for example cpe:2.3:a:apache:http_server:2.4.58. Several lines are searched one after the other and combined.

## `keywords` (type: `array`):

Words to find in the CVE description, one search per line. Several words on one line must all appear (not necessarily together). Leave empty to skip.

## `keywordExactMatch` (type: `boolean`):

Tick this to require the whole line, for example "Microsoft Outlook", to appear as a phrase in the description.

## `cveIds` (type: `array`):

Look up these CVE ids directly, one per line, for example CVE-2024-3094. Up to 100. Other filters are still applied.

## `cweId` (type: `string`):

Only CVEs with this weakness type, for example CWE-79 (cross-site scripting) or CWE-89 (SQL injection). Leave empty for all.

## `severity` (type: `string`):

Only CVEs with this CVSS severity. With CVSS v3, the filter needs a CVSS v3 score, so a CVE that has none yet is not returned.

## `severityVersion` (type: `string`):

Which CVSS version the severity above refers to. Almost all CVEs have a v3 score; v4 is rarer. Ignored when severity is Any severity.

## `minScore` (type: `number`):

Only CVEs whose highest CVSS base score (v3.x or v4.0) is at least this, from 0 to 10, for example 7 for High and above. CVEs with no score are left out when this is above 0. Applied after reading, so CVEs that miss it are not charged.

## `kevOnly` (type: `boolean`):

Only CVEs that appear in CISA's Known Exploited Vulnerabilities catalog (exploitation in the wild). The KEV date, due date, required action and name are returned for them.

## `publishedSince` (type: `string`):

Only CVEs published on or after this. Use a date such as 2026-10-01, a date and time in UTC such as 2026-10-01T08:00:00, or a relative value such as 7 days. If you set no filter at all, the Actor uses the last 7 days.

## `publishedUntil` (type: `string`):

Only CVEs published on or before this. Same formats as above. Empty means now.

## `modifiedSince` (type: `string`):

Only CVEs whose record was last changed on or after this, same formats as above. Useful to catch re-scored or updated CVEs, for example 2 days.

## `modifiedUntil` (type: `string`):

Only CVEs last changed on or before this. Same formats as above. Empty means now.

## `noRejected` (type: `boolean`):

Skip CVE records that were rejected (withdrawn, duplicates). Untick to include them.

## `maxResults` (type: `integer`):

How many CVEs to return, newest first. You pay per CVE returned. With the minimum score, v4 severity or the new-only output, the Actor reads past CVEs that do not qualify until it has found this many.

## `output` (type: `string`):

With the last two, CVEs you already got in an earlier run of the same search (and that have not changed) are skipped and not charged. The first run returns everything, because there is nothing to compare with yet.

## `apiKey` (type: `string`):

Optional. Your own free key from nvd.nist.gov/developers/request-an-api-key. Without a key NVD allows 5 requests per 30 seconds per IP address and the Actor waits 6.5 seconds between requests; with a key it waits 0.7 seconds. Use only your own key; it is sent to NVD in a request header only; the Actor never logs it or writes it to the dataset.

## Actor input object example

```json
{
  "products": [
    "jetbrains:youtrack"
  ],
  "keywordExactMatch": false,
  "severity": "ANY",
  "severityVersion": "v3",
  "kevOnly": false,
  "noRejected": true,
  "maxResults": 100,
  "output": "all"
}
```

# Actor output Schema

## `cves` (type: `string`):

Description, CVSS scores, CWE, affected products and KEV status for each CVE.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "products": [
        "jetbrains:youtrack"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("northbell/nvd-cve-scraper").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = { "products": ["jetbrains:youtrack"] }

# Run the Actor and wait for it to finish
run = client.actor("northbell/nvd-cve-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "products": [
    "jetbrains:youtrack"
  ]
}' |
apify call northbell/nvd-cve-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,northbell/nvd-cve-scraper"
        }
    }
}
```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/vBXLn4Sd012QWLkp5/builds/UrManj0c620VhNsBE/openapi.json
