13 · API · Command line

The vulnerabilitydata command

Every dataset on this site from a terminal or an agent. Piped output is stable JSON and nothing else, errors go to stderr, exit codes never change meaning, and the whole command catalog is one JSON call away. No key, no sign-up.

Install

It needs Node.js 20 or newer, or Bun. The script downloads the bundle and its published SHA-256, refuses the bundle unless they match, and installs a vulnerabilitydata launcher in ~/.local/bin.

curl -fsSL https://vulnerabilitydata.io/cli/install.sh | sh

Later, vulnerabilitydata update replaces itself with the latest build under the same check. The bundle is one file with no dependencies, and its checksum sits beside it. The installer reads these overrides:

VariableMeaning
VULNERABILITYDATA_INSTALL_BASEWhere to download from (default https://vulnerabilitydata.io/cli). Must be https, except for localhost.
VULNERABILITYDATA_INSTALL_DIRWhere the bundle goes (default ~/.local/share/vulnerabilitydata).
VULNERABILITYDATA_BIN_DIRWhere the vulnerabilitydata launcher goes (default ~/.local/bin).

To check the bundle by hand instead, download it with its checksum and compare them; shasum prints OK only when they match.

curl -fsSLO https://vulnerabilitydata.io/cli/vulnerabilitydata.js
curl -fsSLO https://vulnerabilitydata.io/cli/vulnerabilitydata.js.sha256
shasum -a 256 -c vulnerabilitydata.js.sha256

To uninstall, delete the launcher and the bundle (or the directories you set with the overrides above). Nothing else is written: no config file, no credentials, no cache.

rm ~/.local/bin/vulnerabilitydata
rm -r ~/.local/share/vulnerabilitydata

Use from an agent

Start with the catalog. It lists every command with its arguments, flags, examples and JSON output shape, plus the exit codes and environment, so an agent can drive the tool from it alone.

vulnerabilitydata help --json

Whenever stdout is not a terminal, or with --json, stdout carries exactly one JSON document. A failure prints nothing on stdout and one line of JSON on stderr, such as {"error": {"code": "rate_limited", "message": "…", "status": 429, "retry_after": 17, "exit_code": 4}}, and exits with its fixed code. Branch on the exit code or the error's code, never on the message text, and on exit 4 wait retry_after seconds before trying again. On a terminal the same commands print tables. NO_COLOR and --no-color turn colour off.

Commands

Ten commands. Each reads the public files under /api/v1; none needs a key.

datasetsList every dataset with its records, update cadence and description

vulnerabilitydata datasets

Reads the API index: every dataset the site draws, with what it holds, how many records it has, how often it updates and where its numbers come from.

# A table of every dataset.
vulnerabilitydata datasets
# Just the names.
vulnerabilitydata datasets --json | jq -r '.datasets[].name'

JSON output {"api", "version", "updated", "base_url", "licence", "rules", "reproduce", "datasets": [{"name", "description", "url", "records", "updates", "provenance"}]}: the index unchanged.

Calls GET /api/v1/index.json

getPrint one dataset exactly as the site uses it

vulnerabilitydata get <dataset>

Fetches one dataset file. Under --json (or piped) stdout is the file byte for byte as the API serves it. On a terminal it prints the file's fields and provenance; add --json for the full file.

ArgumentMeaning
<dataset>A dataset name from `vulnerabilitydata datasets`, such as hypotheses or live-tte.
# The hypotheses file.
vulnerabilitydata get hypotheses --json
# The latest time-to-exploit month.
vulnerabilitydata get live-tte | jq '.monthly[-1]'

JSON output The dataset file unchanged.

Calls GET /api/v1/<dataset>.json

hypothesesList the outcome hypotheses, or show one in full

vulnerabilitydata hypotheses [id]

Each hypothesis says what AI predicts, what the best non-AI explanation predicts, the falsifier, the series it reads and its evaluation date. None is shown as true or false before that date. Pass an id (or its leading H-number, such as H3) to show one.

ArgumentMeaning
<id> optionalA hypothesis id, or its leading H-number (H1, H2, …).
# Every hypothesis with its evaluation date.
vulnerabilitydata hypotheses
# One hypothesis in full.
vulnerabilitydata hypotheses H3
# Each falsifier and its date.
vulnerabilitydata hypotheses --json | jq '.hypotheses[] | {title, falsifier, evaluate_on}'

JSON output The hypotheses file unchanged: {"_provenance", "note", "hypotheses": [{"id", "title", "registered_on", "revision", "ai_predicts", "non_ai_predicts", "falsifier", "series", "test_window", "evaluate_on"}]}. With an id: {"hypothesis": Hypothesis}.

Calls GET /api/v1/hypotheses.json

ledgerList documented AI incidents, filtered by tool, outcome, evidence or date

vulnerabilitydata ledger [--kind <kind>] [--tool-class <class>] [--outcome <level>] [--grade <grade>] [--since <YYYY-MM-DD>] [--limit <n>]

The AI-involvement ledger: every documented case where AI was involved, one row per actor or tool per primary document, each with its kind of AI tool, the attack stage, the outcome reached, its evidence grade, the source URL and the quoted span. Rows come newest first. A count by kind of AI shows what each observer could see, not how common each kind is.

FlagMeaning
--kind <kind>Only rows of this kind: attack, defense or demonstration.
--tool-class <closed-hosted|open-weight-hosted|open-weight-self-hosted|harness-agent|deepfake-gen|unknown>Only rows with this kind of AI tool.
--outcome <attempt|disrupted|intrusion|victims-named|loss-quantified>Only rows that reached this outcome.
--grade <independently-confirmed|authority-or-victim-confirmed|provider-self-reported|research-demonstration|asserted>Only rows with this evidence grade.
--since <YYYY-MM-DD>Only rows dated on or after this day.
-n, --limit <n>At most this many rows, 1 to 1000 (default: all).
# Independently confirmed cases only.
vulnerabilitydata ledger --grade independently-confirmed
# This year's attack-harness rows, as JSON.
vulnerabilitydata ledger --tool-class harness-agent --since 2026-01-01 --json

JSON output {"total": number, "count": number, "filters": {...}, "incidents": [Incident]}. total counts the whole ledger; count the rows returned.

Calls GET /api/v1/ai-incidents.json

liveShow one live monthly series

vulnerabilitydata live <series> [--last <n>]

The series collected weekly from public feeds, as one row per month. The current month is partial and is named in partial_month. A month a source has no figure for is null, never zero.

ArgumentMeaning
<series>Which series. One of: tte, breaches, ca-ag, hhs-ocr, sec-8k, ai-credited-cves, cve-mix.
FlagMeaning
--last <n>Only the latest n months (1 to 600).
# A year of time to exploit.
vulnerabilitydata live tte --last 12
# Every breach population by month, as JSON.
vulnerabilitydata live breaches --json

JSON output {"series", "dataset", "partial_month", "fetched_at", "columns": [string], "rows": [{"month", column: number|null}]}.

Calls GET /api/v1/live-tte.json · GET /api/v1/live-breaches.json · GET /api/v1/live-ca-ag.json · GET /api/v1/live-hhs-ocr.json · GET /api/v1/live-sec-8k.json · GET /api/v1/live-ai-credited-cves.json · GET /api/v1/live-cve-mix.json

sourcesList every source URL behind the data, and which datasets cite it

vulnerabilitydata sources [--dataset <dataset>]

Reads every dataset (or only --dataset) and collects each source URL its rows and provenance cite, with the datasets that cite it.

FlagMeaning
--dataset <dataset>Only the sources one dataset cites.
# The reports behind the outcome figures.
vulnerabilitydata sources --dataset outcome-reports
# Every source URL.
vulnerabilitydata sources --json | jq -r '.sources[].url'

JSON output {"count": number, "datasets": [string], "sources": [{"url", "datasets": [string]}]}, sorted by URL.

Calls GET /api/v1/index.json · GET /api/v1/<dataset>.json

updateReplace this CLI with the latest published build

vulnerabilitydata update [--check]

Downloads the latest vulnerabilitydata.js and its SHA-256 from the site, refuses it unless the hash matches, and replaces this file in place. --check only reports.

FlagMeaning
--checkReport whether an update exists without installing it.
# Update in place.
vulnerabilitydata update

JSON output {"updated": boolean, "up_to_date": boolean, "path", "sha256"}

Calls GET /cli/vulnerabilitydata.js · GET /cli/vulnerabilitydata.js.sha256

completionPrint a shell completion script

vulnerabilitydata completion <bash|zsh|fish>

Prints a completion script for bash, zsh or fish. It always prints the script (it is meant for a shell); with --json it prints {"shell", "script"}.

ArgumentMeaning
<shell>Your shell. One of: bash, zsh, fish.
# Install for zsh.
vulnerabilitydata completion zsh > "${fpath[1]}/_vulnerabilitydata"
# Load for this bash session.
eval "$(vulnerabilitydata completion bash)"
# Install for fish.
vulnerabilitydata completion fish > ~/.config/fish/completions/vulnerabilitydata.fish

JSON output The script. With --json: {"shell", "script"}.

Calls nothing: it runs without a network request

versionPrint the CLI version

vulnerabilitydata version

The CLI version and the runtime running it.

# Print the version.
vulnerabilitydata version

JSON output {"name": "vulnerabilitydata", "version", "runtime"}

Calls nothing: it runs without a network request

helpShow help for the CLI or one command

vulnerabilitydata help [command]

Text help on a terminal. With --json (or piped) the full machine-readable catalog: every command, flag, exit code, live series and environment variable, so an agent can drive the CLI from it alone.

ArgumentMeaning
<command> optionalA command name.
# Help for one command.
vulnerabilitydata help ledger
# The whole catalog, for agents.
vulnerabilitydata help --json

JSON output {"name", "version", "docs", "api_index", "commands": [CommandSpec], "global_flags", "exit_codes", "error_codes", "environment", "live_series"}, or one CommandSpec for help <command>.

Calls nothing: it runs without a network request

Datasets

The names vulnerabilitydata get takes, the same as the files on the API page.

DatasetWhat it holds
ai-discoveryVulnerabilities found with AI and reported by defenders, with the counter-evidence against reading them as a trend.
ai-incidentsThe ledger: every documented incident where AI was involved, with tool class, attack stage, outcome reached and evidence grade, each quoted from a primary document.
attacker-trendsZero-days exploited in the wild, time to exploit, and Google's 2026 exploitation counts, as each publisher states them.
breachesAnnual breach series from ITRC, Verizon DBIR and IBM, each kept as its source reported it.
conjecturesStanding conjectures, each with its refutation condition, computed status and status history.
cve-macroAnnual CVE totals, the NVD backlog and the growth in CVE numbering authorities.
cwe-typesWeakness-type rankings and their trends.
defender-capacityQuoted reports of incident-response firms at capacity and of security teams unable to triage their alerts, with counter-evidence. Each row says who said it, whether its source ties the strain to AI, and whether the source sells a remedy. Collected reports, not a measurement.
hypothesesOutcome hypotheses about AI, each with what AI predicts, the best non-AI rival, its falsifier, its series and a fixed evaluation date.
instrument-changesDated changes in how a source counts, so a change in counting is never read as an effect of AI.
live-ai-credited-cvesCVEs per month whose record credits an AI tool on a published, versioned list. A floor, never a share.
live-breachesMonthly breach counts from six separate populations (SEC filings, leak sites, Have I Been Pwned, California AG notices, HHS OCR reports), never summed.
live-ca-agMonthly breach notices filed with the California Attorney General.
live-cve-mixCVEs per month by the numbering authority that published them, with each authority's severity scores and counts for a versioned list of weakness classes.
live-hhs-ocrMonthly HIPAA breach reports to the HHS Office for Civil Rights.
live-sec-8kSEC 8-K cybersecurity filings under Items 1.05 and 8.01, with the incident dates each filing states.
live-tteTime to exploit: days from a CVE's publication to its CISA KEV listing, by month.
outcome-reportsOutcome figures from nine report families (losses, ransom paid, insurance claims, attacker speed, dwell time), one row per edition and metric with its quote.
patch-tuesdayMicrosoft Patch Tuesday CVE counts by month since 2018.

Live series

The names vulnerabilitydata live takes. Each reads one weekly-collected dataset and prints one row per month.

SeriesDatasetWhat it shows
ttelive-tteDays from a CVE's publication to its CISA KEV listing, by listing month: CVE count, median days, and the share listed within 0, 7 and 30 days.
breacheslive-breachesMonthly counts from six separate breach populations, one column each, never summed.
ca-aglive-ca-agBreach notices filed with the California Attorney General, by month filed.
hhs-ocrlive-hhs-ocrHIPAA breaches reported to the HHS Office for Civil Rights, by month submitted.
sec-8klive-sec-8kSEC 8-K Item 8.01 cybersecurity disclosures by month. Item 1.05 filings by month are a column of the breaches series.
ai-credited-cveslive-ai-credited-cvesCVEs published per month and those whose record credits an AI tool. A floor, never AI's share.
cve-mixlive-cve-mixCVEs published per month; with --json, each month splits by numbering authority into severity and tracked weakness-class counts.

Global flags

These work with every command.

FlagMeaning
--jsonPrint only JSON to stdout; errors go to stderr as JSON. The default when stdout is not a terminal.
--no-colorTurn off colour. NO_COLOR in the environment does the same.
--base-url <url>Site origin to read from. Defaults to VULNERABILITYDATA_BASE_URL, then https://vulnerabilitydata.io. Must be https, except for localhost.
--timeout <seconds>Give up on a request after this many seconds (default 30).
-h, --helpShow help for the command.

Exit codes

Fixed. A code is never renumbered; new ones are added at the end. Codes 2 and 3 are unused because this API has no accounts.

CodeNameMeaning
0okThe command did what it was asked.
1usageBad arguments, an unknown command, flag or dataset, or a request the API answered 400 or 404.
4rate_limitedThe per-IP rate limit was hit (429). The error carries retry_after in seconds.
5serverA server error (5xx), a network failure, a timeout, or a response the CLI could not read.

The JSON error's code field is finer than the exit code. Each value and the exit code it carries:

Error codeExitWhen
usage1Bad arguments, or an unknown command, flag, dataset or series.
bad_request1The API answered 400, 405 or 422.
not_found1The API answered 404: no dataset by that name.
rate_limited4The API answered 429. The error carries retry_after in seconds.
server5The API answered 5xx, or sent something that is not the JSON expected.
network5No answer: a connection failure or a timeout.

Environment

Read on every run. Rate limits, which every command shares with any other client on the same IP address, are on Rate limits.

VariableMeaning
VULNERABILITYDATA_BASE_URLSite origin, as --base-url. Tests point it at a local server.
NO_COLORAny value turns off colour.