# CVE Monitor — New NVD Vulnerabilities for Your Watchlist (`harvestworks/cve-monitor`) Actor

New CVEs from the official NIST NVD for the vendors and products you watch, with CVSS v3/v4 scores, CWEs, affected CPEs and CISA KEV status. Schedule it to get only vulnerabilities published or updated since the last run.

- **URL**: https://apify.com/harvestworks/cve-monitor.md
- **Developed by:** [Tucker Watts](https://apify.com/harvestworks) (community)
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $3.00 / 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.

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

## CVE Monitor — New Vulnerabilities for Your Vendors & Products (NVD)

Watch the vendors and products you run and get every new CVE from the official NIST National Vulnerability Database (NVD) as clean JSON, with CVSS v3/v4 scores, CWEs, affected CPEs and CISA KEV status. Schedule it and each run returns **only CVEs you haven't seen yet**.

- **Official source, no scraping.** Reads the NVD CVE API 2.0 directly. No browser, no proxies, no login.
- **Alerts, not dumps.** On a schedule you get only new CVEs, and pay only for those. A quiet day costs just the run start.
- **Know what's being exploited.** Every row says whether the CVE is in CISA's Known Exploited Vulnerabilities catalog (with the date added and the remediation due date) and carries CISA's exploitation status (`none`, `poc`, `active`) when available.
- **Updates too, if you want them.** Turn on `includeUpdated` to also get CVEs that were re-scored, got CPE data, or were added to KEV, and a CVE you already have comes back when it changes.
- **Never crashes on a bad input.** Bad keywords, malformed CPE names and NVD outages come back as free `error` rows that say what happened.

### What you can do with it

- Get alerted when a new vulnerability is published for software in your stack (e.g. "Fortinet", "Apache Tomcat", "Citrix NetScaler").
- Track new critical CVEs for the vendors your customers use, for an MSP, SOC or vulnerability-management feed.
- Find out the day a CVE you care about lands in CISA KEV.
- Feed new CVEs to Slack, a ticketing system, or an AI agent that triages them.

### Input

At least one keyword or CPE name is required.

| Field | Required | Description |
|---|---|---|
| `keywords` | \* | Vendor or product names matched in the CVE description, case-insensitive. A multi-word phrase matches exactly; a single word also matches words that start with it. |
| `cpeNames` | \* | CPE 2.3 names for precise matching, e.g. `cpe:2.3:a:apache:tomcat` (all versions) or `cpe:2.3:o:microsoft:windows_10:1607` (one version). |
| `minSeverity` | no | `NONE` (default, includes unscored CVEs), `LOW`, `MEDIUM`, `HIGH` or `CRITICAL`. Uses the higher of the CVSS v4.0 and v3.x base severities. |
| `includeUpdated` | no | Also return older CVEs modified in the window, and re-send delivered CVEs when they change. Default `false`. |
| `lookbackDays` | no | Window in days, 1–120 (the NVD API's limit). Default `7`. |
| `onlyNew` | no | Skip CVEs a previous run with the same keywords and CPE names already returned. Default `true`. |
| `maxResults` | no | Stop after this many CVEs per run. Default `1000`. The rest come next run. |
| `nvdApiKey` | no | Your own free [NVD API key](https://nvd.nist.gov/developers/request-an-api-key) (stored as a secret). Makes runs about 6× faster. |

Keywords and CPE names together: up to 25 per run.

```json
{
  "keywords": ["Fortinet", "Apache Tomcat", "Citrix"],
  "cpeNames": ["cpe:2.3:a:jfrog:artifactory"],
  "minSeverity": "HIGH",
  "lookbackDays": 7
}
```

**Monitoring:** schedule this input daily. The first run returns the last 7 days; each later run returns only what's new. NVD asks automated clients to poll no more than once every two hours.
**One-off search:** set `onlyNew` to `false` and `lookbackDays` to the window you want.

### Output

One row per CVE, most recently modified first per keyword or CPE name:

```json
{
  "type": "cve",
  "id": "CVE-2026-42016",
  "change": "updated",
  "matchedBy": "JFrog",
  "published": "2026-07-27T20:16:39.613Z",
  "lastModified": "2026-09-12T04:16:32.483Z",
  "status": "Analyzed",
  "description": "JFrog Artifactory (Self Hosted) versions before 7.133.11 are vulnerable to a privilege escalation attack due to a validation check of the token signature/issuer and not the token’s scope.",
  "severity": "HIGH",
  "cvssV3Score": 8.8,
  "cvssV3Severity": "HIGH",
  "cvssV3Vector": "CVSS:3.1/AV:N/AC:L/PR:L/UI:N/S:U/C:H/I:H/A:H",
  "cvssV4Score": null,
  "cvssV4Severity": null,
  "cvssV4Vector": null,
  "cweIds": ["CWE-863"],
  "vendorProducts": ["jfrog:artifactory"],
  "affectedCpes": ["cpe:2.3:a:jfrog:artifactory:*:*:*:*:*:-:*:* (<7.133.11)"],
  "affectedCpeCount": 1,
  "cnaAffected": ["jfrog artifactory"],
  "inCisaKev": true,
  "cisaExploitAdd": "2026-09-11",
  "cisaActionDue": "2026-09-25",
  "cisaRequiredAction": "Apply mitigations in accordance with vendor instructions, ...",
  "cisaVulnerabilityName": "JFrog Artifactory Incorrect Authorization Vulnerability",
  "exploitation": "active",
  "tags": [],
  "references": [
    "https://docs.jfrog.com/releases/docs/jfrog-security-advisories",
    "https://www.cisa.gov/known-exploited-vulnerabilities-catalog?field_cve=CVE-2026-42016"
  ],
  "nvdUrl": "https://nvd.nist.gov/vuln/detail/CVE-2026-42016"
}
```

- `change` is `new` for a CVE first published in the window and never sent before, `updated` for an older CVE modified in the window or one sent before that changed (only with `includeUpdated`).
- `status` is NVD's analysis status: `Received`, `Awaiting Analysis`, `Undergoing Analysis`, `Analyzed`, `Modified` or `Deferred`. Many new CVEs are never fully analyzed by NVD (`Deferred`); they still have the CNA's description, score and `cnaAffected` products, but `vendorProducts` and `affectedCpes` stay empty.
- `severity` is the higher of the v4.0 and v3.x base severities, or `null` if the CVE has no score yet. Scores prefer NVD's own (`Primary`) and fall back to the CNA's.
- `affectedCpes` lists vulnerable CPE match criteria with version ranges, capped at 25 (`affectedCpeCount` has the full count). `references` is capped at 25.
- `exploitation` is CISA's SSVC exploitation status (`none`, `poc`, `active`) when CISA has assessed the CVE, otherwise `null`.
- All timestamps are UTC. Rejected CVEs are left out.

#### Errors: free rows

```json
{ "type": "error", "target": "cpe:2.3:a:apache", "reason": "invalid_input", "message": "\"cpe:2.3:a:apache\" is not a CPE 2.3 name. Use the form cpe:2.3:a:vendor:product[:version], e.g. \"cpe:2.3:a:apache:tomcat\"." }
```

`reason` is one of `invalid_input`, `invalid_api_key`, `rate_limited`, `unavailable`, `network_error`. A per-keyword run summary is saved to the `OUTPUT` record of the run's key-value store.

### Pricing

Pay per event: **$3 per 1,000 CVEs** ($0.003 each), plus $0.002 per run start. `error` rows are free, and with `onlyNew` you never pay twice for the same CVE (with `includeUpdated`, a CVE that changes is sent, and charged, again).

Set a **maximum charge per run** to cap spending. When the run reaches it, it stops cleanly and says so. CVEs that didn't fit are returned on the next run.

### Limits

- Keyword search looks at the CVE description only, the way NVD's own search does. Use CPE names for exact product matching, and keywords for brand-new CVEs NVD hasn't analyzed yet.
- CPE matching only finds CVEs NVD has analyzed, which can take days, or never happen for `Deferred` CVEs.
- Up to 25 keywords and CPE names per run, and a look-back of up to 120 days (the NVD API's maximum). For very broad keywords, at most the newest 10,000 matches per keyword are checked; the run summary says when that happens.
- Without an API key, the Actor waits about 6.5 seconds between requests to respect NVD's public limit of 5 requests per 30 seconds, so a 25-item watchlist takes about 3 minutes. With your own key, about 1 second. If NVD still refuses (HTTP 403), the Actor waits and retries, then stops with a clear `rate_limited` message instead of failing. It never tries to get around a limit.
- Public vulnerability data only; no personal data.

### Use with AI agents

The input and output are flat and predictable. The `type` field on every row tells CVEs and errors apart, and every error has a fixed `reason` code. An agent can call this Actor with just `keywords`, and filter on `severity`, `inCisaKev` or `exploitation`.

***

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

# Actor input Schema

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

Vendor or product names to watch, e.g. "Apache Tomcat", "Fortinet", "WordPress". Matched against the CVE description (case-insensitive). A phrase with several words matches only that exact phrase; a single word also matches longer words that start with it ("tomcat" matches "tomcats"). Keywords and CPE names together: up to 25 per run. Add at least one keyword or CPE name.

## `cpeNames` (type: `array`):

Precise product matching via NVD's CPE data, e.g. "cpe:2.3:a:apache:tomcat" (every version) or "cpe:2.3:o:microsoft:windows_10:1607" (one version, version ranges apply). Only CVEs NVD has already analyzed carry CPE data, so very new CVEs may show up here later than under keywords. Find CPE names at nvd.nist.gov/products/cpe/search.

## `minSeverity` (type: `string`):

Only CVEs whose CVSS v4.0 or v3.x base severity (whichever is higher) is at least this. CVEs without a score yet are left out when this is set; they are returned once scored if still inside the look-back window.

## `includeUpdated` (type: `boolean`):

Also return older CVEs that were modified in the look-back window (new score, CPEs, CISA KEV listing, references), and return a delivered CVE again when it changes. Off: only CVEs first published in the window.

## `lookbackDays` (type: `integer`):

Only CVEs published (or, with "Include updated CVEs", modified) in the last N days. 1-120; 120 days is the NVD API's limit.

## `onlyNew` (type: `boolean`):

Skip CVEs a previous run with the same keywords and CPE names already returned. On by default for API calls and schedules; unchecked in this form so a first try shows results. Turn it on when you schedule the Actor (e.g. daily) to get only new CVEs each time.

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

Stop after this many CVEs. With "Only new CVEs" on, the rest are returned on the next run.

## `nvdApiKey` (type: `string`):

Your own free NVD API key (request one at nvd.nist.gov/developers/request-an-api-key). Without it, the Actor waits about 6.5 s between requests to stay under NVD's public limit of 5 requests per 30 seconds; with it, about 1 s. NVD's terms say a key must not be shared, so use your own.

## Actor input object example

```json
{
  "keywords": [
    "WordPress",
    "Apache"
  ],
  "minSeverity": "NONE",
  "includeUpdated": false,
  "lookbackDays": 7,
  "onlyNew": false,
  "maxResults": 1000
}
```

# Actor output Schema

## `results` (type: `string`):

All rows. Each row's "type" is "cve" or "error".

## `cvesTable` (type: `string`):

Key CVE fields.

## `summary` (type: `string`):

Per keyword / CPE status, result counts, the date window, and whether a limit stopped the run.

# 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 = {
    "keywords": [
        "WordPress",
        "Apache"
    ],
    "lookbackDays": 7,
    "onlyNew": false
};

// Run the Actor and wait for it to finish
const run = await client.actor("harvestworks/cve-monitor").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 = {
    "keywords": [
        "WordPress",
        "Apache",
    ],
    "lookbackDays": 7,
    "onlyNew": False,
}

# Run the Actor and wait for it to finish
run = client.actor("harvestworks/cve-monitor").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 '{
  "keywords": [
    "WordPress",
    "Apache"
  ],
  "lookbackDays": 7,
  "onlyNew": false
}' |
apify call harvestworks/cve-monitor --silent --output-dataset

```

## MCP server setup

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

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/WzFNJ8JocZucAia4h/builds/CqJz9NXCUXLgi9q0i/openapi.json
