---
name: nist-nvd-api-ingestion
description: "How to get NIST National Vulnerability Database API data into a pandas DataFrame and Parquet: access, the request, the format, limits, quirks and terms."
---

# Load one NVD CVE API record into pandas and Parquet

Source entry: https://signal-lab-jet.vercel.app/datasets/nist-nvd-api
Provider: https://nvd.nist.gov/developers/vulnerabilities
Checked against the provider's documentation: 2026-11-01

## Access
- No key is required for public-rate access. A free API key may be sent in the apiKey request header for the higher limit.

## Request
```bash
curl 'https://services.nvd.nist.gov/rest/json/cves/2.0?cveId=CVE-2021-44228'
```

## Format
JSON response metadata and a vulnerabilities array containing CVE identifiers, source, dates, status, descriptions, metrics, weaknesses, affected configurations and references.

## Load into pandas and Parquet
Needs Python 3 with requests, pandas and pyarrow.
```python
"""One NVD CVE API 2.0 record -> pandas -> Parquet. No key."""
import requests
import pandas as pd

URL = "https://services.nvd.nist.gov/rest/json/cves/2.0"
r = requests.get(URL, params={"cveId": "CVE-2021-44228"}, timeout=60)
r.raise_for_status()
rows = []
for item in r.json()["vulnerabilities"]:
    cve = item["cve"]
    description = next((x["value"] for x in cve.get("descriptions", []) if x["lang"] == "en"), None)
    rows.append({"id": cve["id"], "sourceIdentifier": cve["sourceIdentifier"],
                 "published": cve["published"], "lastModified": cve["lastModified"],
                 "vulnStatus": cve["vulnStatus"], "description": description})
df = pd.DataFrame(rows)
df["published"] = pd.to_datetime(df["published"], utc=True)
df["lastModified"] = pd.to_datetime(df["lastModified"], utc=True)
df.to_parquet("nvd_cve.parquet", index=False)
print(len(df), "CVE", df.iloc[0]["id"], "modified", df.iloc[0]["lastModified"].isoformat())
```
Run by us on 2026-11-01 (python 3.13.5 | pandas 3.1.0 | pyarrow 26.0.0 | requests 2.34.2). Result: 1 CVE CVE-2021-44228 modified 2026-08-11T19:33:44.513000+00:00

## Limits
- Public limit: 5 requests per rolling 30 seconds without an API key.
- Free-key limit: 50 requests per rolling 30 seconds.
- The CVE API returns at most 2,000 records per page; use startIndex for pagination.

## Quirks
- Use published for the original CVE publication time and lastModified to drive incremental refreshes.
- A CVE can carry several CVSS versions and several source-specific metrics; preserve the nested metrics when scores matter.
- Affected-product logic is nested under configurations and CPE match criteria rather than a flat product list.

## Terms and attribution
- NVD API services may search, display, analyze and retrieve NVD data under the NVD terms and NIST website policies.
- Display the requested non-endorsement notice in services that use the API; do not attribute modified content to NVD.
- Terms page: https://nvd.nist.gov/developers/terms-of-use

## Sources
- https://nvd.nist.gov/main-QN4PLKKZ.js: "The CVE API is used to easily retrieve information on a single CVE or a collection of CVE from the NVD."
- https://nvd.nist.gov/main-QN4PLKKZ.js: "The public rate limit (without an API key) is 5 requests in a rolling 30 second window; the rate limit with an API key is 50 requests in a rolling 30 second window."
- https://www.nist.gov/copyrights-disclaimers: "With the exception of material marked as copyrighted, information presented on NIST sites are considered public information and may be distributed or copied."

## Help improve this skill
Missing a source, or see something to improve? Call the MCP tool suggest_source or feedback (or POST /api/suggest or /api/feedback). Reviewed ideas: https://signal-lab-jet.vercel.app/agent-suggestions

Information for educational purposes only. Free tiers, limits and licenses belong to the providers and may change; check the provider's own terms before using the data.
