Quick start
Ask for today’s brief — new high and critical CVEs, fresh additions to CISA’s exploited list, and the latest breaches:
curl https://spydr.io Then narrow it down to what you run:
curl "https://spydr.io/threats?q=openssl&limit=3"
spydr · threats · q=openssl 163 results · synced 20:44 UTC
──────────────────────────────────────────────────────────────────────────────────────────
8.7 high CVE-2026-74891 2026-08-17 EPSS 0.52% jahlives openssl_encrypt
openssl_encrypt versions before 1.4.0 contain hardcoded database credentia…
9.3 critical CVE-2026-81696 2026-08-27 EPSS 0.25% jahlives openssl_encrypt
openssl_encrypt versions before 1.4.9 fail to sanitize terminal control ch…
9.3 critical CVE-2026-81695 2026-08-27 EPSS 0.25% jahlives openssl_encrypt
openssl_encrypt versions before 1.4.9 fail to escape attacker-controlled k…
──────────────────────────────────────────────────────────────────────────────────────────
page 1 of 55 · web: https://spydr.io/threats?q=openssl&limit=3 · next: &page=2
scripts: add &format=json (or ndjson, csv, rss) · help: curl https://spydr.io/help
Data: This product uses data from the NVD API but is not endorsed or certified by the NVD. CISA KEV · FIRST EPSS.
Open the same URL in a browser and you get the web version. The filters are identical, so you can build a
query on the site and paste it into a script. Run curl https://spydr.io/help for a cheat sheet.
One URL, many formats
Spydr picks a format from, in order:
- a suffix —
/threats.json,.ndjson,.csv,.rssor.txt— or aformat=parameter; - an Accept header asking for JSON, NDJSON, CSV, RSS or plain text;
- a command-line client — curl, wget, HTTPie, xh or PowerShell get a text table;
- everything else — browsers, link previews, crawlers — gets the web page.
Text sent to a terminal is coloured. Add color=0, or use the .txt suffix, for plain output you can pipe into
grep or a log. Upstream text is stripped of control characters, so nothing in a CVE description can rewrite your terminal.
Endpoints
| Path | What it returns |
|---|---|
/ | Today’s brief (text or JSON; browsers get the home page). |
/threats | CVEs, newest first, with filters below. |
/cve/CVE-2024-3400 | One CVE in full: scores, exploitation, EPSS, references. Fetched from the NVD on demand if we don’t have it yet. |
/breaches | Data breaches, newest additions first. |
/help | A cheat sheet for terminals. |
Threat filters
| Parameter | Example | Meaning |
|---|---|---|
q | q=nginx,openssl | Keywords. Commas mean OR, spaces mean AND. CVE ids work too (q=CVE-2024-3400). |
cvss | cvss=7 | Minimum CVSS base score, 0–10. |
severity | severity=critical,high | One or more of critical, high, medium, low, none. |
exploited | exploited=1 | Only CVEs in CISA KEV, or with active exploitation reported through CISA’s SSVC data. |
kev | kev=1 | Only CVEs in CISA’s Known Exploited Vulnerabilities catalog. With kev=1, since= filters on the date CISA added it. |
epss | epss=0.1 | Minimum EPSS probability of exploitation in the next 30 days, 0–1. |
since | since=7d | Published after: 24h, 7d, 2w, 3m or a date like 2026-09-01. |
vendor, product | vendor=microsoft | Match the vendor or product name. |
sort | sort=score | relevance (default with q), published (default), score, epss, kev. |
limit, page | limit=50&page=2 | Up to 200 per page. |
Unknown parameters are ignored and reported in warnings (JSON) or as a note (text). Invalid values return 400 with an explanation.
Breach filters
| Parameter | Example | Meaning |
|---|---|---|
q | q=adobe.com | Company name or domain. |
since | since=30d | Added to Have I Been Pwned after this. |
accounts | accounts=1000000 | Minimum number of affected accounts. |
data | data=passwords | Exposed data class, e.g. passwords, credit cards, phone numbers. |
sort | sort=size | added (default), breach (breach date) or size. |
limit, page | limit=50 | Up to 200 per page. |
Output & headers
| Parameter | Example | Meaning |
|---|---|---|
format | format=json | text, json, ndjson, csv or rss — or use a suffix: /threats.json, /breaches.rss. |
color | color=0 | Plain text for terminals (colour is only added when the response goes to a terminal). |
width | width=140 | Text width in columns, 60–240. Default 100. |
fail | fail=1 | Respond 409 Conflict when anything matches, 200 when nothing does. Made for CI gates. |
JSON responses look like this (trimmed):
{
"query": { "q": "openssl", "cvss": "7" },
"count": 3, "total": 12, "page": 1, "limit": 20,
"updated": { "cves": "2026-09-23T05:43:00Z", "kev": "…", "epss": "…" },
"links": { "web": "https://spydr.io/threats?q=openssl&cvss=7", "next": "…" },
"warnings": [],
"results": [
{
"id": "CVE-2026-0000",
"url": "https://spydr.io/cve/CVE-2026-0000",
"published": "2026-09-22T15:17:24Z",
"score": 9.8, "severity": "critical", "cvss_version": "3.1",
"vector": "CVSS:3.1/AV:N/AC:L/PR:N/UI:N/S:U/C:H/I:H/A:H",
"epss": 0.42, "epss_percentile": 0.97,
"exploited": true,
"kev": { "added": "2026-09-22", "due": "2026-10-13", "action": "…", "ransomware": "Unknown" },
"vendors": ["…"], "products": ["…"], "cwes": ["CWE-787"],
"description": "…"
}
],
"attribution": [ { "source": "NVD", "url": "https://nvd.nist.gov", "notice": "…" } ]
} Useful response headers:
X-Spydr-Count— total matches, handy withcurl -I.ETag— send it back asIf-None-Matchand you’ll get304 Not Modifiedwhen nothing changed.Access-Control-Allow-Origin: *— data formats can be fetched from browser code.
Automation recipes
Gate a build on new critical CVEs
With fail=1, Spydr answers 409 when anything matches and 200 when nothing does. Check the status code
rather than relying on curl -f, which also fails on network errors and rate limits:
code=$(curl -s -o hits.txt -w '%{http_code}' \
"https://spydr.io/threats?q=nginx,openssl&cvss=9&since=1d&fail=1")
case $code in
200) echo "No new critical CVEs" ;;
409) cat hits.txt; exit 1 ;; # something matched
*) echo "Spydr unavailable ($code)"; exit 2 ;;
esac GitHub Actions
name: security-feed
on:
schedule:
- cron: "0 7 * * 1-5" # weekdays, 07:00 UTC
pull_request:
jobs:
spydr:
runs-on: ubuntu-latest
steps:
- name: Fail on new critical or exploited CVEs in our stack
run: |
code=$(curl -s -o hits.txt -w '%{http_code}' \
"https://spydr.io/threats?q=django,celery,redis,postgresql&cvss=9&since=1d&fail=1")
cat hits.txt
case $code in 200) ;; 409) exit 1 ;; *) echo "::warning::Spydr unavailable ($code)" ;; esac Post exploited CVEs to Slack
#!/bin/sh
# crontab: 0 * * * * /usr/local/bin/spydr-slack
curl -s "https://spydr.io/threats.json?q=nginx,postgres,openssl&exploited=1&since=1h" \
| jq -r '.results[] | "*\(.id)* \(.severity) — \(.products[0] // "")\n\(.url)"' \
| while read -r line; do
curl -s -X POST -H 'content-type: application/json' \
-d "$(jq -n --arg t "$line" '{text:$t}')" "$SLACK_WEBHOOK_URL"
done jq, NDJSON and CSV
# ids of everything added to KEV in the last day
curl -s "https://spydr.io/threats.json?kev=1&since=24h" | jq -r '.results[].id'
# stream results into another tool, one JSON object per line
curl -s "https://spydr.io/threats.ndjson?q=kubernetes&cvss=7" | while read -r cve; do
echo "$cve" | jq -r '"\(.id) \(.score)"'
done
# spreadsheet-ready
curl -s -o breaches.csv "https://spydr.io/breaches.csv?since=90d&accounts=1000000" PowerShell
# PowerShell parses JSON for you
$feed = Invoke-RestMethod "https://spydr.io/threats.json?kev=1&since=7d"
$feed.results | Format-Table id, score, severity, @{n='product';e={$_.products[0]}}
# Or the terminal view
curl.exe "https://spydr.io/threats?exploited=1" Feed readers
Any list is also an RSS feed: add .rss to the path. For example https://spydr.io/threats.rss?exploited=1 for newly exploited CVEs, or
https://spydr.io/breaches.rss for breaches.
Limits & caching
Each client can make 120 requests a minute. Past that you’ll get 429 Too Many Requests with a
Retry-After header. The data only changes every hour or two, so polling more often than every 15 minutes gains nothing.
Responses for explicit formats (a suffix or format=) are cacheable for five minutes; fail=1 responses are never cached.
Where the data comes from
- CVEs — NVD
- Everything published in the last 120 days plus every CVE on CISA’s exploited list, refreshed every two hours. The score shown is the newest CVSS version available (4.0, then 3.1, then 3.0), preferring NVD’s own assessment over the reporting organisation’s. Many new CVEs are scored only by the organisation that reported them.
- Exploitation — CISA KEV and SSVC
- “Exploited” means the CVE is in CISA’s Known Exploited Vulnerabilities catalog, or CISA’s SSVC assessment records active exploitation. Refreshed hourly.
- Exploit prediction — FIRST EPSS
- The probability a CVE will be exploited in the next 30 days, updated daily.
- Breaches — Have I Been Pwned
- Publicly disclosed breaches, refreshed every six hours. Breaches flagged as fabricated, spam lists or retired are left out. Licensed under CC BY 4.0.
This product uses data from the NVD API but is not endorsed or certified by the NVD.