ThreatFilter exposes a small JSON API at https://api.threatfilter.dev.
Every endpoint is unauthenticated, free, CORS-enabled, and cached for a few minutes at
the Cloudflare edge. Rate-limit: be reasonable — there is no key and no per-IP enforcement
today.
Tags returned in vendors, severity_label, exploitation_status, and
sectors come from the upstream feeds. The dedicated ML classifier is currently
unfunded, so most items ship with vendors: [] and these are filled in
heuristically in the browser (and at /feed.xml) using the keyword catalog in
src/lib/classify.ts.
GET/health
Health check
Lightweight liveness probe. Returns 200 with a constant payload — useful for uptime monitors.
Example request
curl https://api.threatfilter.dev/health
Example response
{
"ok": true,
"service": "threatfilter-api"
}
GET/sources
Source catalog + last fetch status
List every ingested feed source with its kind (rss/json/atom), category, last fetched_at, and last status.
Static vendor catalog (slug, label, category) annotated with the count of items currently linked to each vendor (when the materialized vendor_counts table is populated).
Keyset-paginated advisory feed ordered by published_at DESC, id DESC. Cursor is returned in next_cursor — feed it back as ?cursor= to get the next page. All filter params combine with AND.
Parameters
Name
Type
Description
Example
limit
int
Page size (default 50, max 100).
50
cursor
string
Opaque cursor from a previous response's next_cursor field.
vendors
csv
Comma-separated vendor slugs. Items matching any of these vendors are returned (OR).
cisco,fortinet
severity
csv
One or more of critical, high, medium, low, info (OR).
critical,high
exploitation
csv
exploited | poc_available | unproven (OR).
exploited
geo
csv
ISO-3166 alpha-2 country codes (OR).
US,EU
sec
csv
Sector slugs (OR). Same vocabulary as /sector/<slug> pages.
{
"items": [
{
"id": 482301,
"source_id": "cisa-kev",
"title": "CISA adds CVE-2026-12345 to Known Exploited Vulnerabilities",
"url": "https://www.cisa.gov/known-exploited-vulnerabilities-catalog",
"published_at": "2026-05-20T10:45:00Z",
"fetched_at": "2026-05-20T11:02:14Z",
"raw_summary": "A critical authentication bypass in a popular VPN appliance is being actively exploited in the wild…",
"severity_cvss": 9.8,
"severity_label": "critical",
"vendors": [],
"products": [],
"target_countries": [],
"exploitation_status": null,
"sectors": []
}
],
"next_cursor": "eyJ0cyI6IjIwMjYtMDUtMjBUMTA6NDU6MDBaIiwiaWQiOjQ4MjMwMX0="
}
POST/digest/subscribe
Subscribe to the daily email digest
Body is JSON: { email, vendors?, severity?, sectors? }. Triggers a double-opt-in email — subscription is only active once /digest/verify is hit with the token. The API never returns email addresses or PII.
Parameters
Name
Type
Description
Example
email (required)
string (body)
Recipient address. Validated with a permissive RFC-5322 regex.
A drop-in JavaScript widget renders the latest advisories on any third-party page —
see the live demo + snippet at /embed. Under the hood
it calls /items exactly like the homepage does.
RSS / Atom
A filtered RSS feed is available at /feed.xml. It accepts the
same v=, sec=, tf= parameters the homepage filter UI
uses, so any combination of facets can be saved as a feed URL.