๐Ÿ›ก๏ธ Vulners Python SDK

August 21, 2026 ยท View on GitHub

๐Ÿ›ก๏ธ Vulners Python SDK

The official Python client for Vulners โ€” the vulnerability intelligence graph to build on

Query CVEs, exploits and advisories enriched with CVSS, EPSS and exploitation status; assess your software, hosts and SBOMs for the vulnerabilities that affect them; and stream the whole graph for your own pipelines โ€” all from a few lines of typed, async-ready Python.

PyPI version Python versions Downloads CI License: MIT Typed

SDK documentation ยท Data models ยท Get an API key ยท Vulners.com


Why Vulners?

Vulners aggregates 230+ sources โ€” CVEs, exploits, vendor advisories, CISA KEV, EPSS and AI risk scores โ€” into one queryable vulnerability-intelligence graph, so you can prioritize what to fix beyond raw CVSS. It is API-first and needs no agents or network access: send asset data in standard formats, get back risk-prioritized intelligence.

This SDK is the fastest way to build on that graph from Python:

  • ๐Ÿ”Ž Intelligence โ€” search and enrich CVEs, bulletins and advisories with CVSS, EPSS, KEV and exploitation context
  • ๐Ÿงจ Exploits โ€” track active exploitation and pull proof-of-concept code for a product or CVE
  • ๐Ÿ–ฅ๏ธ Assessment โ€” find the vulnerabilities affecting your software, Linux/Windows hosts, KBs, libraries and SBOMs
  • ๐Ÿ—„๏ธ Datasets โ€” stream the full graph (and hourly updates) into your own pipelines and mirrors
  • ๐Ÿ”” Alerts โ€” subscribe to new vulnerabilities matching a query and get notified via webhook
  • ๐Ÿค– AI-ready โ€” a built-in MCP server, typed bulletin models and documented response shapes to ground AI agents on live vulnerability facts

Installation

pip install -U vulners

Requires Python 3.10+. A plain pip install vulners pulls everything needed for fast, modern transport โ€” httpx, pydantic and orjson, plus HTTP/2 (h2), response compression (brotli/zstandard), ISA-L-accelerated gzip (isal) and streaming archive decode (ijson/stream-unzip) โ€” all with prebuilt wheels, so there is no build step.

From a branch checkout (unreleased)

The latest pre-release lives on the v4.0 branch (not yet on PyPI). Check the branch out and install it from source:

git clone -b v4.0 https://github.com/vulnersCom/api.git
cd api
pip install -e .        # editable install from the checkout

Or install that branch directly, without cloning:

pip install "git+https://github.com/vulnersCom/api.git@v4.0"

Quickstart

from vulners import Vulners

# Get a free API key at https://vulners.com (or export VULNERS_API_KEY).
with Vulners(api_key="YOUR_API_KEY_HERE") as v:
    # Look up a CVE โ€” you get back a typed model (or None if it isn't found).
    log4shell = v.search.get_bulletin("CVE-2021-44228")
    if log4shell is not None and log4shell.cvss is not None:
        print(log4shell.id, "โ€”", log4shell.title)
        print(log4shell.cvss.score, log4shell.cvss.vector)

    # Search with Lucene syntax. `limit` is the page size; read the first page here
    # (iterating the page itself auto-paginates the whole result window).
    page = v.search.query("type:cve AND cvss.score:[9 TO 10]", limit=10)
    for bulletin in page.data:
        print(bulletin.id, bulletin.title)

Tip: keep your key out of source code โ€” read it from the environment:

import os
from vulners import Vulners
v = Vulners(api_key=os.environ["VULNERS_API_KEY"])

Async

The same API is available on AsyncVulners:

import asyncio
from vulners import AsyncVulners

async def main():
    async with AsyncVulners(api_key="YOUR_API_KEY_HERE") as v:
        page = await v.search.query("Fortinet AND RCE", limit=20)
        for bulletin in page.data:
            print(bulletin.id, bulletin.title)

asyncio.run(main())

Usage examples

Runnable scripts for every task live under samples/ โ€” a v4 set and a matching v3 (legacy) set, side by side.

Find public exploits for a CVE

for exploit in v.search.query("bulletinFamily:exploit AND CVE-2023-20198", limit=10).data:
    print(exploit.id, exploit.href)

Audit installed software for known CVEs

# Mix product/version dicts and raw CPE 2.3 strings.
for item in v.audit.software([{"product": "openssl", "version": "1.0.1"},
                              "cpe:2.3:a:apache:log4j:2.14.1"]):
    print(item["matched_criteria"], "->", len(item["vulnerabilities"]), "vulnerabilities")

Audit a Linux host by installed packages

report = v.audit.linux_audit(os_name="debian", os_version="10",
                             packages=["openssl 1.1.1d-0+deb10u3 amd64"])
for issue in report["issues"]:
    print(issue["package"])

Look up a package's license

from vulners import Vulners

with Vulners(api_key="YOUR_API_KEY_HERE") as v:
    meta = v.audit.metadata("pypi", "requests", "2.28.0")
    print(meta.license)          # ['ISC']  โ€” always a list, never a bare string

    # An empty license with meta.found is True means "known, but no recorded license".
    # meta.found is False when the registry does not know the package name at all.
    unknown = v.audit.metadata("pypi", "no-such-package", "9.9.9")
    print(unknown.found)         # False

    # For Maven the name is the "groupId:artifactId" coordinate; the registry name is
    # lower-cased for you, so you never touch the colon-vs-slash / casing details.
    guava = v.audit.metadata("maven", "com.google.guava:guava", "30.0-jre")
    print(guava.license)         # ['Apache-2.0']

Stream the archive (lazily, without buffering gigabytes)

for record in v.archive.iter_collection("cve"):
    ...  # each record is yielded as it arrives (a lazily-streamed JSON array)

Handle errors

from vulners import Vulners, APIError, RateLimitError

try:
    with Vulners(api_key="YOUR_API_KEY_HERE") as v:
        cve = v.search.get_bulletin("CVE-2021-44228")
except RateLimitError as err:
    print("slow down; retry after", err.retry_after, "s")
except APIError as err:
    print(err.status_code, err.error_code, err.message)   # the server's problem description

Data models

Every document the API returns is a bulletin, and the SDK models them in three typed layers, so your editor and type checker know the exact shape at whatever level of detail you need:

  • Bulletin โ€” the base fields every document carries (id, title, cvss, published, โ€ฆ).
  • Family models (CveBulletin, ExploitBulletin, ScannerBulletin, โ€ฆ) โ€” one per bulletinFamily, adding that family's shared fields.
  • Collection models โ€” one per collection type, adding the fields specific to that source.

search/archive/audit return the most specific model that fits a document (type โ†’ bulletinFamily โ†’ Bulletin). Every field is optional (a missing one is None) and every model keeps extra="allow", so a field the API adds before the SDK models it is still on the object โ€” nothing is ever dropped.

from vulners import Vulners, CveBulletin

with Vulners() as v:                          # reads VULNERS_API_KEY
    cve = v.search.get_bulletin("CVE-2021-44228")
    if isinstance(cve, CveBulletin):
        print(cve.cwe)                        # typed, cve-specific field โ€” IDE-completed

The full hierarchy โ€” every family and collection with its fields, descriptions and examples, generated from live data โ€” is browsable in the Data models reference.


Proxies

Route traffic through a proxy with proxy=, or let the client pick up the standard proxy environment variables:

from vulners import Vulners

# explicit (a URL, or httpx.Proxy(..., auth=(user, pass)) for an authenticated proxy)
v = Vulners(api_key="YOUR_API_KEY_HERE", proxy="http://proxy.corp.example:8080")

# or from the environment โ€” HTTPS_PROXY / HTTP_PROXY / ALL_PROXY, honoring NO_PROXY:
#   export HTTPS_PROXY="http://proxy.corp.example:8080"
v = Vulners(api_key="YOUR_API_KEY_HERE")

Environment proxies are used when you don't pass proxy= and leave trust_env=True (the default). See Proxies, timeouts & retries for authenticated proxies and combining a proxy with custom TLS.


AI agents (MCP)

Ship live Vulners intelligence to AI agents and copilots via the built-in Model Context Protocol server:

pip install "vulners[mcp]"
VULNERS_API_KEY=... vulners-mcp        # run the MCP server

It exposes concise, typed tools โ€” search bulletins, look up a CVE, find exploits, and audit software/Linux/hosts โ€” that any MCP-compatible client (Claude, IDE agents, โ€ฆ) can call. See AGENTS.md.

Hosted vs. bundled. For a fully managed, always-on endpoint, use the official hosted server at https://mcp.vulners.com/ โ€” no install required. The vulners-mcp shipped in this package is a minimal, self-hosted implementation (a core set of tools) for embedding in your own environment.


Backward compatibility

Upgrading from 3.x is a drop-in. The entire v3 API โ€” VulnersApi, VScannerApi, every method, and all import paths โ€” is preserved unchanged in 4.0:

import vulners
api = vulners.VulnersApi(api_key="YOUR_API_KEY_HERE")   # still works exactly as before
cve = api.search.get_bulletin("CVE-2021-44228")         # returns a dict, as it always did

New code should prefer the Vulners / AsyncVulners clients above. Migrate at your own pace โ€” see the migration guide.


Getting an API key

  1. Create a free account at vulners.com.
  2. Follow the authentication guide to generate a key.
  3. Pass it to Vulners(api_key=...), or export VULNERS_API_KEY and let the client read it.

Never commit your API key. The SDK authenticates with the X-Api-Key header; a few legacy endpoints additionally send the key where the server requires it โ€” in the request body (the subscription and webhook mutations and win_audit) or the query string (webhooks.read()). On every request it strips the key on cross-origin redirects, refuses redirects to internal addresses, and keeps it out of exception messages and object reprs.


Documentation

ResourceLink
๐Ÿ“˜ SDK documentationhttps://vulnersCom.github.io/api/
๐Ÿงฌ Data models (bulletin hierarchy)https://vulnersCom.github.io/api/reference/bulletins/
๐Ÿ”Œ SDK API reference (clients, resources, exceptions)https://vulnersCom.github.io/api/reference/clients/
๐Ÿงญ Migration (v3 โ†’ v4)https://vulnersCom.github.io/api/explanation/migration/
๐Ÿ“– Vulners platform docshttps://docs.vulners.com/docs/
๐Ÿงช Interactive API (Swagger)https://docs.vulners.com/docs/api/swagger/
๐Ÿ”‘ Authentication / API keyshttps://docs.vulners.com/docs/quickstart/authentication/
๐Ÿ’ก Examplessamples/
๐Ÿค ContributingCONTRIBUTING.md
๐Ÿ”’ Security policySECURITY.md

Compatibility

  • Python: 3.10, 3.11, 3.12, 3.13, 3.14
  • Platforms: Linux, macOS, Windows
  • Vulners API: v3 and v4 endpoints

Contributing

Issues and pull requests are welcome! Please open an issue to discuss substantial changes first. The project uses uv:

uv sync
make check   # lint + typecheck + unasync-check + tests

See CONTRIBUTING.md for the full workflow.


Security

Found a security issue in the SDK? Please report it privately โ€” see SECURITY.md. Do not open a public issue for vulnerabilities.


License

Distributed under the MIT License. See LICENSE.


Built by the Vulners team. If this SDK helps secure your stack, please โญ the repo โ€” it helps others find it.

Keywords: vulnerability intelligence ยท CVE ยท exploit intelligence ยท CVSS ยท EPSS ยท CISA KEV ยท risk prioritization ยท security advisories ยท SBOM ยท vulnerability assessment ยท vulnerability scanner ยท threat intelligence ยท vulnerability database ยท AI security agents ยท MCP ยท MSSP ยท DevSecOps ยท Python security ยท infosec