Skip to content

API Overview ​

The Vulnpatch API provides programmatic access to vulnerability data aggregated from multiple sources.

Base URL ​

https://api.vulnpatch.dev/api/v1/

Endpoints Summary ​

Every route below is served today and described in openapi.json, except where a row says otherwise. A test in the repository checks that the router, the spec and these pages name the same routes, so a route missing from this page is a defect rather than an omission.

Nixpkgs-Specific Endpoints ​

These endpoints return data only from nixpkgs security issues and the nixpkgs repository:

MethodEndpointDescription
GET/nix/statsCounts of open nixpkgs security issues
GET/nix/cvesOne page of the newest open nixpkgs security issues filed by the automated matcher, with linked PRs; partial is always true. Use /issues for every issue
GET/nix/channelsWhere each NixOS channel stands, as NixOS's monitoring reports it; inferred only when no reading is held, and the body says which
GET/nix/aheadNew CVEs mapped to nixpkgs attributes as they arrive, with each channel's version against the affected ranges and when the security tracker filed
GET/nix/channels/history?channel=Every observed change to one channel's revision or status, paged
GET/nix/repology/:packageThe versions each nixpkgs channel carries, from Repology
GET/nix/hydra/:packageLatest Hydra builds of a package, per platform
GET/nix/pr/:number/backportsWhether a PR merged and which release branches carry a backport
GET/nix/stable/:series/containment/:shaWhen a commit reached a stable channel release
GET/cve/:id/nix/channelsFix status of a CVE per NixOS channel
GET/cve/:id/fix-timing?commit=When a named fix commit reached each stable channel
GET/issuesList nixpkgs security issues (severity-enriched, with difficulty estimates)
GET/issues/:idGet a specific nixpkgs security issue by number
GET/package/:name/prsRecent nixpkgs pull requests mentioning a package
GET/sourcesList available data sources

Multi-Ecosystem Endpoints ​

These endpoints aggregate data from OSV.dev across 38+ ecosystems (npm, PyPI, Debian, etc.):

MethodEndpointDescription
GET/statsGet aggregate statistics across all sources
GET/ecosystem-statsGet aggregate ecosystem vulnerability counts
GET/ecosystem-severity/:ecosystemSeverity breakdown for one ecosystem
GET/recent-advisoriesGet advisories published in last 12 hours
GET/osv/:packageGet vulnerabilities from OSV.dev
GET/vulns/:packageGet CVE matches with confidence scores
GET/osv-details/:idGet detailed vulnerability information
GET/packages/indexEvery package name with at least one advisory recorded
GET/search/package/:nameVulnerabilities affecting a package, across sources
GET/package/:name/historyEvery OSV vulnerability for a package, newest first

CVE Endpoints ​

Direct CVE lookup from the official MITRE CVE List V5:

MethodEndpointDescription
GET/cve/:idGet CVE details by ID (includes EPSS + KEV + data quality score inline)
GET/cve/:id/dossierAgent-readable CVE dossier with provenance, quality gaps, ingest hints, and links back to cve.vulnpatch.dev
GET/cve/:id/verifyRe-read the record upstream, uncached, immediately before acting
GET/cve/:id/provenanceWhat each upstream source said about the CVE, and when it changed
GET/cve/:id/osvThe nixpkgs mapping as an OSV record
GET/aliases/:idAny advisory id (GHSA, RUSTSEC, DSA, ...) to the CVEs it names
GET/relations/:idThe relationship graph around a CVE, advisory, package or weakness, each edge with its source
POST/cve/batchBulk lookup up to 50 CVEs
POST/cve/statusStatus badges for a list of CVEs
GET/cve/:id/historyGet CVE change history
GET/cve/:id/at/:dateQuery CVE state at specific date
GET/search?q=term&sort=dateFull-text search across CVEs (sort: date/severity)
GET/mitre/recent?limit=50Latest CVEs from MITRE delta feed (~24h ahead of NVD)

Exploitability Intelligence ​

MethodEndpointDescription
GET/exploitabilityEPSS scores + CISA KEV status for tracked CVEs
GET/kev/recentThe latest additions to the CISA KEV catalogue
GET/newly-actionableCVEs whose EPSS score recently crossed the threshold
GET/cve/:id/lifecycleFull vulnerability lifecycle timeline (disclosure to patch)
GET/cve/:id/exploit-signalsWeaponization signals (PoC repos, Nuclei, ExploitDB)
GET/cve/:id/ai-assessmentAI-generated plain-English impact assessment
GET/fix-etasFix ETA predictions per CVE
GET/rebuild-impactPackage rebuild impact analysis
GET/rebuild-impact/:nameSingle package rebuild impact

Analytics Endpoints ​

MethodEndpointDescription
GET/trendingRecently updated vulnerabilities
GET/analyticsMonthly CVE aggregates by severity, source and ecosystem
GET/severity-breakdownVulnerabilities by severity level
GET/fix-rateFix availability statistics
GET/package-healthPackage maintenance health scores
GET/package-health/:nameHealth score for one package
GET/analytics/time-to-fixHistorical time-to-fix benchmarks
GET/data-quality/statsCVE data quality score distribution

GitHub Security Advisories ​

MethodEndpointDescription
GET/ghsaRecent GitHub Security Advisories, read with the server's own credential; 503 if none is configured

Weekly Digest by Email ​

MethodEndpointDescription
POST/notify/subscribeFollow CVEs and packages; a confirmation email is sent first
POST/notify/confirm/:tokenOpen the confirmation link
GET/notify/subscription/:tokenWhat an address follows
POST/notify/unsubscribe/:tokenUnsubscribe in one click (also the RFC 8058 target)
POST/notify/resubscribe/:tokenUndo an unsubscribe, within 30 days
POST/notify/follows/:tokenReplace what is followed
POST/notify/delete/:tokenDelete everything held for the address

See Weekly Digest by Email.

Remediation Planning ​

MethodEndpointDescription
POST/remediation/planGenerate minimal upgrade plan to fix CVEs
GET/verify-fix?url=&cves=Whether a GitHub release or commit page names the CVE ids given

SBOM & PURL ​

MethodEndpointDescription
GET/purl/:purlPURL vulnerability lookup
POST/sbom/scanAnalyze an SBOM, no credential, 100 components
POST/sbomThe same operation at the same limits
POST/sbom/time-travelAnalyze SBOM exposure at a past date
GET/sbom/formatsSupported SBOM formats, PURL types and the enforced limits

cve.vulnpatch.dev accepts a CycloneDX or SPDX SBOM as JSON and sends it to /sbom; the vulnerability report downloads as JSON. The site does not convert lockfiles. Generate the SBOM with your ecosystem's tooling first. A flake.lock is not supported: it pins a nixpkgs revision, not a package list, and which packages that revision carries is not yet indexed.

Source hashes ​

MethodEndpointDescription
POST/prefetch/:operationNix source and Go vendor hashes without a local Nix; see Source hashes

Feeds ​

MethodEndpointDescription
GET/feed/rssRSS feed of recent advisories
GET/feed/atomAtom feed of recent advisories
GET/feed/osv/nixpkgsThe nixpkgs mapping as a bulk OSV feed

/feed/rss and /feed/atom also answer at the host root, without /api/v1.

Knowledge Graph ​

Relationship questions are answered by Relations, /relations/:id above, from the search index and the dossier. The older Neo4j backend is not deployed: one route under /graph answers, from OSV; the rest return 503 with code: "GRAPH_UNAVAILABLE". See Knowledge Graph.

MethodEndpointDescription
GET/graph/package/:name/vulns?ecosystem=CVEs affecting a package in one ecosystem, from OSV

Service and Utility Endpoints ​

MethodEndpointDescription
GET/statusWhether the answer you are about to get can be trusted
GET/freshnessMeasured ingest latency per source
GET/nvd/statusProgress of the NVD backfill and sync
GET/healthHealth check
GET/versionAPI version info
GET/openapi.jsonOpenAPI specification
GET/agent-manifestThe agent manifest; also at /.well-known/vulnpatch-agent.json

/health, /version and /openapi.json also answer at the host root. The API host serves /llms.txt and /.well-known/security.txt as well.

Dashboard routes ​

POST /access-request, GET /access-request/:username, POST /pr/validate and POST /pr/fix exist for the private-beta dashboard, require the caller's GitHub token and are deliberately outside the public contract and the spec. POST /pr/signature is retired and answers 410. See Dashboard routes.

Common Parameters ​

Query Parameters ​

ParameterTypeDescription
ecosystemstringFilter by ecosystem (e.g., npm, PyPI, Debian)
versionstringFilter by package version

Headers ​

HeaderDescription
AcceptAlways returns application/json

Response Format ​

Success Response ​

json
{
  "success": true,
  "data": {
    // Endpoint-specific data
  },
  "timestamp": "2024-01-15T12:00:00.000Z"
}

A few routes answer without the envelope, and their pages say so: /nix/channels, /nix/stable/:series/containment/:sha, /mitre/recent, /packages/index, /cve/:id/osv, /feed/osv/nixpkgs, /agent-manifest and the two XML feeds.

Error Response ​

json
{
  "success": false,
  "error": "Error message describing what went wrong"
}

HTTP Status Codes ​

CodeDescription
200Success (may include a placeholder when a CVE is allocated but not yet published; see below)
400Bad request (invalid parameters)
404Resource not found; for CVE endpoints, includes a stable code field. An unknown path answers JSON naming the spec
405The path exists and does not take that method; Allow names the ones it does
429Rate limit exceeded
500Internal server error
502An upstream this answer depends on could not be read
503This service cannot answer yet: a feed not built, an index unreadable, a backend not deployed

CVE endpoints: status contract ​

GET /api/v1/cve/:id and GET /api/v1/cve/:id/dossier share the same availability contract:

  • Published: 200 with full data.
  • Allocated but not yet enriched (the id is in the MITRE delta feed): 200 with a minimal record. Lookup sets status.type = "UNPUBLISHED"; dossier sets canonical.availability = "awaiting_ingest" and the X-Dossier-Availability response header.
  • Reserved / Rejected / Withdrawn (MITRE acknowledges the id with that state): 200. The dossier's canonical.availability carries the exact state.
  • Unknown (no authority has allocated the id): 404 with a structured body:
json
{
  "success": false,
  "error": "not_found",
  "code": "CVE_UNKNOWN",
  "hint": "No authority has allocated CVE-9999-99999. Verify the ID follows the CVE-YYYY-NNNNN+ format and check for typos."
}

Clients should branch on code, not the free-text error message.

CORS ​

The API supports CORS for browser-based applications. All origins are allowed for read-only endpoints.

Caching ​

Responses include cache headers:

HeaderDescription
X-CacheHIT if served from cache, MISS otherwise
Cache-ControlBrowser caching directives

Rate Limiting ​

One Cloudflare edge rule is enforced: 2 requests per 10 seconds per address on the SBOM analysis paths and /cve/:id/ai-assessment. Every other route carries advisory X-RateLimit-* headers from a per-instance counter that is not an account-wide budget. There are no tiers and no credential raises a limit. See Rate Limits for the headers, the 429 bodies and how to behave around them.

OpenAPI Specification ​

The full API specification is available at:

https://api.vulnpatch.dev/openapi.json

Use this to auto-generate clients in your language of choice with tools like OpenAPI Generator.

SDKs & Libraries ​

Currently, there are no official SDKs. The API is designed to be easily consumed with standard HTTP clients:

bash
curl https://api.vulnpatch.dev/api/v1/stats
javascript
const response = await fetch('https://api.vulnpatch.dev/api/v1/stats');
const data = await response.json();
python
import requests
response = requests.get('https://api.vulnpatch.dev/api/v1/stats')
data = response.json()