cbcvebase.
API reference

cvebase API documentation

Search 1.5M+ security documents across 90+ sources. Get CVE details, EPSS scores, CISA KEV status, affected versions, exploits, and detection rules — all over a JSON HTTP API or natively from any MCP-compatible AI client.

Base URL
https://cvebase.io
Format
JSON over HTTPS

Quickstart

Three steps to your first successful API call.

  1. 1

    Get an API key

    Create a personal API key in your dashboard. API keys require a Pro or Team subscription — the Free tier uses session-based auth through the web and MCP only.

  2. 2

    Make your first request

    Send your key in the Authorization header:

    curl -H "Authorization: Bearer cvb_xxx" \
      "https://cvebase.io/api/cve/CVE-2021-44228"
  3. 3

    Parse the response

    You'll get back a JSON payload with the overview, enrichment signals, affected versions, and related documents:

    {
      "cve_id": "CVE-2021-44228",
      "severity": "CRITICAL",
      "cvss": 10.0,
      "enrichment": {
        "epss": { "score": 0.976, "percentile": 0.999 },
        "kev": { "in_kev": true, "date_added": "2021-12-10" },
        "exploit_available": true,
        "exploited_in_wild": true
      },
      "total_documents": 239
    }
Trying before buying?
The read-only GET endpoints (search, CVE detail, trending, EPSS history) accept anonymous requests at 10/day per IP — no header required. The POST /api/cve/batchendpoint requires authentication, and API keys themselves require a Pro or Team subscription — Free accounts can't create keys.

Authentication

The cvebase API uses bearer token authentication. Pass your API key in the Authorization header on every request:

Authorization: Bearer cvb_xxx

Real keys are cvb_followed by 48 hex characters (52 total, 192 bits of entropy). You see the full key once at creation time — store it in a password manager or secret store, and never commit it to source control. If you lose a key, you can't recover it; revoke and create a new one.

Store your key in an environment variable

export CVEBASE_API_KEY="cvb_..."  # paste the key from your dashboard
Who can create API keys?
All tiers. Free accounts get 1 API key capped at 50 requests/day, Pro gets 1 key at 500/day, Team gets 5 keys each at 5,000/day. Upgrades and downgrades propagate to existing keys within ~60 seconds — no need to re-issue after a plan change.
If you suspect a key has been leaked, revoke it immediately from the keys dashboard. Revocation takes effect within seconds.

Rate limits

Two independent daily counters apply, both on a rolling 24-hour sliding window:

  • API calls/day — every request to /api/search, /api/cve/..., /api/trending, MCP tool calls, and similar.
  • Batch calls/day — separate counter for POST /api/cve/batch. Doesn't consume from the general API budget. Each batch call can enrich up to the tier's batch-size cap in one shot.
TierAPI calls/dayBatch sizeBatch calls/dayAPI keys
Anonymous (no header)10blockedblocked
Free501051
Pro500100501
Team5,0005005005
Detection rules on Free
/api/search strips Sigma, YARA, Suricata, and Nuclei detection rules from results for Free and anonymous callers. The per-CVE detail endpoints /api/cve/{id} and /api/cve/{id}/documents return everything — those power the public SEO-indexable CVE pages and need the full picture for search engines.

Response headers

Successful responses on rate-limited endpoints carry:

  • X-RateLimit-LimitYour daily request budget.
  • X-RateLimit-RemainingRequests left in the current window.
  • X-RateLimit-ResetUnix timestamp when the window rolls over.

429 responses carry a Retry-After header (seconds until reset) and a body with retry_after_seconds. The X-RateLimit-* triple isn't set on 429s — rely on the Retry-After header instead.

Sleep for the advertised Retry-Afteron 429 responses — don't retry tighter than once per second. If you're regularly hitting the limit, upgrade or batch smarter.

Errors

Errors use conventional HTTP status codes. The body is always a JSON object with an error field containing a machine-readable code and a human-readable message:

{
  "error": {
    "code": "rate_limit_exceeded",
    "message": "Daily rate limit reached",
    "retry_after_seconds": 14820
  }
}
StatusCodeWhen it happens
401invalid_api_keyThe Authorization header is missing, malformed, or references a revoked key. Also returned for expired OAuth tokens as invalid_token.
401authentication_requiredEndpoint requires auth but no credentials were sent. Returned by POST /api/cve/batch for anonymous callers.
403key_limit_reachedYou already have the maximum number of active keys for your tier (Free: 1, Pro: 1, Team: 5). Revoke an existing key first.
413batch_too_largeBatch body has more CVE IDs than your tier allows (Free: 10, Pro: 100, Team: 500).
422(FastAPI validation)Missing or malformed query parameter — e.g. an invalid CVE ID pattern or a limit out of range. Response body follows the FastAPI default shape with detail[].
429rate_limit_exceededDaily general API quota reached. See the retry_after_seconds field and Retry-After header.
429batch_rate_limit_exceededDaily batch-calls/day quota reached (Free: 5, Pro: 50, Team: 500). This counter is separate from the general API quota.
500internal_errorSomething went wrong on our side. Safe to retry after a short backoff.
Unknown CVE IDs don't return 404. A call like /api/cve/CVE-1999-9999 returns a 200 with total_documents: 0 and empty groups — check that field before you assume the lookup succeeded.

Pagination

List endpoints use limit/offset pagination. Pass limit and offset as query parameters; the response echoes them back alongside a totalcount so you know when you've reached the end.

# Page 1 — first 20 results
curl "https://cvebase.io/api/search?q=log4j&limit=20&offset=0"

# Page 2 — next 20
curl "https://cvebase.io/api/search?q=log4j&limit=20&offset=20"
  • Default limit is 20, maximum 100.
  • Default offset is 0.
  • Ordering is stable within a single query — results are ranked by relevance for searches, and by publication date for document listings.
  • When offset + limit > total, you get a shorter (or empty) page — no error.

Endpoints

Six endpoints cover the full surface area: semantic search, CVE detail, paginated documents per CVE, batch enrichment, trending signals, and EPSS history.

GET/api/cve/{cve_id}

Get a CVE

Full CVE detail: overview, enrichment (EPSS, KEV, exploit availability, wild exploitation), affected versions, and every related document grouped by source type.

Example request
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/cve/CVE-2021-44228"
Example response
{
  "cve_id": "CVE-2021-44228",
  "severity": "CRITICAL",
  "cvss": 10.0,
  "overview": {
    "description": "Apache Log4j2 2.0-beta9 through 2.15.0...",
    "cwes": ["CWE-917"],
    "published_date": "2021-12-10"
  },
  "enrichment": {
    "epss": { "score": 0.976, "percentile": 0.999 },
    "kev": { "in_kev": true, "date_added": "2021-12-10" },
    "exploit_available": true,
    "exploited_in_wild": true
  },
  "affected_versions": [...],
  "total_documents": 239,
  "groups": { "exploit": [...], "detection": [...] }
}
GET/api/cve/{cve_id}/documents

List documents for a CVE

Paginated documents for a single CVE, with an optional source_type filter. Use this when the /cve/{id} response is too heavy — this endpoint only returns document metadata, not the full CVE.

Parameters
limit
integer
Results per page. Default 20, maximum 100.
offset
integer
Pagination offset. Default 0.
source_type
string
Filter by exploit, detection, advisory, threat_intel, research, etc.
Example request
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/cve/CVE-2021-44228/documents?source_type=exploit&limit=5"
Example response
{
  "cve_id": "CVE-2021-44228",
  "total": 49,
  "offset": 0,
  "limit": 5,
  "source_type_counts": { "exploit": 49, "detection": 102 },
  "results": [
    {
      "doc_id": "exploitdb:51183",
      "source": "exploitdb",
      "source_type": "exploit",
      "title": "Apache Log4j 2 — Remote Code Execution",
      "cve_ids": ["CVE-2021-44228"],
      "url": "https://www.exploit-db.com/exploits/51183"
    }
  ]
}
POST/api/cve/batch

Batch CVE enrichment

Enrich many CVEs in a single call — overview, EPSS, KEV status, exploit availability, and affected versions. No documents, so it stays lightweight. Ideal for scanner triage pipelines. Requires authentication (any tier with an API key, or MCP OAuth) — anonymous callers get 401. Consumes a SEPARATE daily counter (batch-calls/day) that doesn't eat into the general API budget.

Parameters
cve_ids
string[]required
Array of CVE IDs. Cap per request: Free 10, Pro 100, Team 500. Over the cap → 413 batch_too_large. Batch-calls/day limit: Free 5, Pro 50, Team 500 → 429 batch_rate_limit_exceeded when exhausted.
Example request
curl -X POST -H "Authorization: Bearer cvb_xxx" \
  -H "Content-Type: application/json" \
  -d '{"cve_ids": ["CVE-2021-44228", "CVE-2024-3094"]}' \
  "https://cvebase.io/api/cve/batch"
Example response
{
  "count": 2,
  "results": [
    {
      "cve_id": "CVE-2021-44228",
      "found": true,
      "overview": { "severity": "CRITICAL", "cvss_score": 10.0 },
      "enrichment": {
        "epss": { "score": 0.976 },
        "kev": { "in_kev": true },
        "exploited_in_wild": true
      },
      "affected_versions": [
        { "ecosystem": "Maven", "package": "log4j-core", "fixed": "2.16.0" }
      ]
    }
  ]
}
GET/api/cve/{cve_id}/epss-history

EPSS score history

Daily EPSS scores for a specific CVE over a given window. Useful for spotting trend changes before they show up in KEV.

Parameters
days
integer
Window length in days. Default 30, maximum 365.
Example request
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/cve/CVE-2021-44228/epss-history?days=90"
Example response
{
  "cve_id": "CVE-2021-44228",
  "history": [
    { "date": "2026-01-05", "score": 0.976, "percentile": 0.999 },
    { "date": "2026-01-06", "score": 0.975, "percentile": 0.999 }
  ]
}
GET/api/products/{vendor}/{product}

Product vulnerabilities (build your vuln feed)

Every CVE affecting a product, with server-side filtering, sorting, and pagination. Combine the risk filters to build a precise feed for a product you run — e.g. P1/P2, ransomware-linked, exploited CVEs affecting a specific version. Slugs are canonical vendor/product (lowercase), e.g. fortinet/fortios, apache/log4j. Not rate-limited.

Parameters
version
string
Keep only CVEs affecting this exact version (range-aware). E.g. 2.14.1.
priority
string
Comma-separated cvebase Priority: P1, P2, P3, P4.
ransomware
boolean
Keep only ransomware-linked CVEs (CISA KEV / VulnCheck).
kev / wild / exploit
boolean
Keep only CISA-KEV / exploited-in-wild / public-exploit CVEs.
severity
string
CRITICAL / HIGH / MEDIUM / LOW.
epss_min
float
Keep only CVEs with EPSS ≥ this (0–1).
cwe
string
Keep only CVEs tagged with this CWE, e.g. CWE-79.
year
string
Keep only CVEs published in this year, e.g. 2025.
sort
string
importance (default), priority_desc, epss_desc, cvss_desc, date_desc, date_asc.
page / per_page
integer
Pagination. per_page max 100.
Example request
# Ransomware-linked, P1/P2 CVEs affecting FortiOS 7.0.0
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/products/fortinet/fortios?priority=P1,P2&ransomware=true&version=7.0.0&sort=priority_desc"
Example response
{
  "slug": "fortinet/fortios",
  "display_name": "Fortinet FortiOS",
  "version": "7.0.0",
  "total": 273,
  "filtered_total": 6,
  "filtered_stats": {
    "kev_count": 6, "ransomware_count": 4,
    "priority_counts": { "P1": 5, "P2": 1, "P3": 0, "P4": 0 }
  },
  "stats": {
    "total_cves": 273, "kev_count": 31, "ransomware_count": 14,
    "priority_counts": { "P1": 21, "P2": 12, "P3": 102, "P4": 138 }
  },
  "cves": [
    {
      "cve_id": "CVE-2024-21762",
      "severity": "CRITICAL", "cvss_score": 9.8, "epss": 0.94,
      "priority": { "level": "P1", "score": 96 },
      "ransomware": true, "in_kev": true,
      "version_match": 1
    }
  ]
}
POST/api/products/match

Match my stack → affecting CVEs

Submit your software stack (products + versions) and get every affecting CVE per item — enriched with cvebase Priority, ransomware association, EPSS, KEV, and a version-match rank. Apply the shared risk filters to get a precise, actionable feed. Requires authentication; tier-limited like /api/cve/batch (items/request: Free 10, Pro 100, Team 500; separate daily call budget). Build it into a scanner/SBOM pipeline or a nightly job.

Parameters
items
object[]required
Array of { product, version? } or { vendor, product, version? }. `product` accepts a name ("log4j"), a slug ("apache/log4j"), or a display name. Omit `version` to match the whole product.
filters
object
Shared risk vocabulary applied to every item: { severity, priority: ["P1","P2"], ransomware, kev, wild, exploit, epss_min }.
max_cves_per_item
integer
Cap CVEs returned per item (default 50, max 200).
sort
string
importance (default), priority_desc, epss_desc, cvss_desc, date_desc.
Example request
curl -X POST -H "Authorization: Bearer cvb_xxx" \
  -H "Content-Type: application/json" \
  -d '{
    "items": [
      {"product": "apache/log4j", "version": "2.14.1"},
      {"vendor": "openssl", "product": "openssl", "version": "3.0.0"},
      {"product": "nginx"}
    ],
    "filters": {"priority": ["P1","P2"], "kev": true}
  }' \
  "https://cvebase.io/api/products/match"
Example response
{
  "results": [
    {
      "input": { "product": "apache/log4j", "version": "2.14.1" },
      "status": "resolved",
      "resolved_slug": "apache/log4j",
      "display_name": "Apache Log4j",
      "total": 2,
      "cves": [
        {
          "cve_id": "CVE-2021-44228",
          "severity": "CRITICAL", "epss": 0.975,
          "priority": { "level": "P1", "score": 98 },
          "ransomware": true, "in_kev": true,
          "version_match": 1
        }
      ]
    },
    { "input": { "product": "nginx" }, "status": "resolved", "total": 24, "cves": [...] }
  ],
  "summary": { "items": 3, "resolved": 3, "unresolved": 0, "total_cves": 26 }
}

MCP integration

cvebase runs a remote Model Context Protocol server at https://cvebase.io/mcp. Add it to Claude, Cursor, or Windsurf and your AI assistant can search vulnerabilities, fetch CVE details, and track threats directly from the conversation — no separate API key required.

Setup

Claude Code (CLI / VS Code / JetBrains):

claude mcp add cvebase --transport streamable-http https://cvebase.io/mcp

Claude Desktop — edit claude_desktop_config.json (Settings → Developer → Edit Config):

{
  "mcpServers": {
    "cvebase": {
      "type": "streamable-http",
      "url": "https://cvebase.io/mcp"
    }
  }
}

Cursor — edit ~/.cursor/mcp.json (or Settings → MCP → Add Server):

{
  "mcpServers": {
    "cvebase": {
      "url": "https://cvebase.io/mcp"
    }
  }
}

Windsurf — edit ~/.codeium/windsurf/mcp_config.json:

{
  "mcpServers": {
    "cvebase": {
      "serverUrl": "https://cvebase.io/mcp"
    }
  }
}

Any other MCP-capable client: point it at https://cvebase.io/mcp with transport streamable-http. OAuth 2.1 discovery lives at /.well-known/oauth-authorization-server.

First-time sign-in flow
  1. Your client opens a browser window the first time a tool is called.
  2. Sign in with GitHub or Google — same accounts as the web app.
  3. Approve the scope, then you're redirected back to your client.
  4. The OAuth token is cached locally. Subsequent calls don't re-prompt.
Anonymous: 10 tool calls/day per IP. Signed in: 50/day on Free, 500/day on Pro, 5,000/day on Team.

Available tools

search_vulnerabilities

Search 1.5M+ documents across 90+ sources. Supports CVE IDs, nicknames, CWE IDs, ATT&CK techniques, and natural language.

get_cve

Full CVE details: description, severity, CVSS, EPSS, CISA KEV status, exploit availability, affected packages.

get_cve_documents

Documents for a CVE filtered by type: exploits, detection rules, advisories, research.

get_trending

Trending vulnerabilities: recent CISA KEV additions, top EPSS scores, exploit statistics.

get_epss_movers

CVEs with the biggest EPSS score changes — rising scores flag increasing threat activity.

list_sources

All 90+ indexed sources with record counts, organized by category.

Example conversation

“What are the most critical vulnerabilities added to CISA KEV this week?”
Claude calls get_trending then get_cve for details.
“Find detection rules for CVE-2024-3400.”
Claude calls get_cve_documents with source_type="detection".
“Which CVEs have rising EPSS scores we should patch first?”
Claude calls get_epss_movers and cross-references with get_cve.

Common workflows

Triage CVEs from a scanner

Send your scan results to the batch endpoint and get back severity, EPSS, CISA KEV status, exploit availability, and fix versions — then prioritize however your team does.

# 1. Batch-enrich CVEs from your scan
curl -X POST -H "Authorization: Bearer cvb_xxx" \
  -H "Content-Type: application/json" \
  -d '{"cve_ids": ["CVE-2021-44228", "CVE-2024-3094", "CVE-2023-44487"]}' \
  "https://cvebase.io/api/cve/batch"

# Returns severity, EPSS, KEV status, exploit_available, affected_versions for each

Deep dive on a CVE

Get the overview, then fetch specific document types — exploits, detection rules, advisories.

# 1. Overview + enrichment + affected versions
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/cve/CVE-2021-44228"

# 2. Get exploit code
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/cve/CVE-2021-44228/documents?source_type=exploit"

# 3. Get detection rules (Sigma, YARA, Suricata)
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/cve/CVE-2021-44228/documents?source_type=detection"

Search across all sources

Semantic search across 1.5M+ documents. Filter by source type to narrow results.

# Search everything
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/search?q=apache+struts+rce"

# Only detection rules
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/search?q=log4j&source_type=detection"

Monitor trending threats

Track new CISA KEV additions, EPSS score changes, and exploit availability over time.

# What's hot today
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/trending"

# Track a specific CVE's EPSS score over 90 days
curl -H "Authorization: Bearer cvb_xxx" \
  "https://cvebase.io/api/cve/CVE-2024-3094/epss-history?days=90"

Source types

Every document belongs to one of these source types. Use them with the source_type parameter on /api/search and /api/cve/{id}/documents.

vulnerability

NVD, GHSA, CVE List — primary vulnerability databases

exploit

ExploitDB, Metasploit, PoC repos — working exploit code

detection

Sigma, Nuclei, YARA, Elastic — detection rules

advisory

Vendor advisories from Microsoft, Cisco, Red Hat, Apple, etc.

threat_intel

Blogs, threat reports, APT analysis from IR firms

research

Wikipedia, academic papers, reference material

discussion

Mailing lists, forums, disclosure threads

framework

MITRE ATT&CK techniques and sub-techniques

Libraries & SDKs

We don't ship an official SDK yet — the API is intentionally small enough that any HTTP client works. Here's the same request in three common languages:

cURL
curl -H "Authorization: Bearer $CVEBASE_API_KEY" \
  "https://cvebase.io/api/cve/CVE-2021-44228"
Python
import os, requests

headers = {"Authorization": f"Bearer {os.environ['CVEBASE_API_KEY']}"}
cve = requests.get(
    "https://cvebase.io/api/cve/CVE-2021-44228",
    headers=headers,
).json()

print(f"CVSS: {cve['cvss']}  EPSS: {cve['enrichment']['epss']['score']}")
print(f"KEV: {cve['enrichment']['kev']['in_kev']}")
JavaScript / TypeScript
const res = await fetch(
  "https://cvebase.io/api/cve/CVE-2021-44228",
  { headers: { Authorization: `Bearer ${process.env.CVEBASE_API_KEY}` } },
);
const cve = await res.json();
console.log(`CVSS: ${cve.cvss}  KEV: ${cve.enrichment.kev.in_kev}`);

Building an SDK or wrapper? Let us know at [email protected] — we'll link it from this page.