Base URL: https://omnomfeeds.com
All responses are application/json; charset=utf-8 except /feed.xml which is RSS 2.0. Methods documented are the supported method; anything else returns 405.
Try one now:
$ curl https://omnomfeeds.com/api/cves/hottest?hours=24&limit=5
/api/cves/hottest, /api/landing/stats, /feed.xml) cache 5-10 minutes server-side. Polling more often is fine - you get the cached payload.| Param | Type | Default | Notes |
|---|---|---|---|
| min_score | int | 0 | Floor on the article score (0-100). |
| limit | int | 100 | Page size. |
| offset | int | 0 | Page offset. |
| source | string | - | Exact source name match. |
| source_type | string | - | rss, bluesky, mastodon, reddit, github, ioc_feed. |
| search | string | - | Substring match across title + summary. |
| has_iocs | bool | false | Only items tagged with IOCs. |
| unread | bool | false | Only items the caller hasn't marked read (per-user state needs auth). |
| show_dupes | bool | false | Include de-duped articles. |
| since | ISO 8601 | - | Articles fetched at or after this timestamp. |
/api/landing/stats for cheap polling.{"status":"ok","version":"<commit-sha>","uptime_s":<n>,"hosted_mode":bool}. UptimeRobot-friendly./api/cve/CVE-2026-12345. Response includes cvss_v3_score, cvss_v3_severity, cwe, published, epss_score, epss_percentile, otx_pulse_count, description.curl https://omnomfeeds.com/api/cve/CVE-2025-50165
| Param | Type | Default | Notes |
|---|---|---|---|
| hours | int 1-336 | 72 | Window size in hours. |
| limit | int 1-50 | 10 | Max rows. |
| Param | Type | Default | Notes |
|---|---|---|---|
| hours | int 1-336 | 72 | Lookback window. |
| min | int | 3 | Min distinct sources mentioning the CVE. |
apt41, lazarus, scattered-spider, lockbit). Response includes display name, aliases, origin attribution where known, recent mention count, and a link to MITRE Groups.curl https://omnomfeeds.com/api/actors/lockbit
cobaltstrike, mimikatz, sliver, redline). Same response shape as actors plus a kind field (loader / RAT / stealer / etc.).T1059, T1059.001.scope=global is public and returns TTP frequency across all sources for the window. scope=mine is Pro-gated and returns the caller's bookmarked articles' TTPs. Drops straight into attack-navigator.| Param | Type | Default | Notes |
|---|---|---|---|
| scope | string | global | global (public) or mine (Pro). |
| days | int 1-180 | 30 | Lookback window for scope=global. |
curl 'https://omnomfeeds.com/api/attack/export?scope=global&days=14' -o layer.json
| Param | Type | Default | Notes |
|---|---|---|---|
| days | int 1-90 | 30 | How far back to fetch briefs. |
These exist for completeness. Hit them anonymously and you get a 401; hit them as a free user in hosted mode and you get a 402.
?force=1 to bypass the 24h auto-hide gate.Standard HTTP status codes. No envelope around errors - plain JSON like {"error":"reason"}.
| Code | Meaning |
|---|---|
| 200 | OK |
| 400 | Bad request - usually malformed query param. |
| 401 | Unauthenticated. Reached a Pro-gated endpoint without a session. |
| 402 | Free tier user hit a Pro endpoint. |
| 404 | Path or resource doesn't exist. |
| 405 | Method not allowed (most endpoints are GET-only). |
| 429 | Per-IP rate limit on AI endpoints (20 per minute). Retry-After header carries seconds. |
| 503 | Backing service (NVD, EPSS, OTX) unreachable for the requested data. |
Same API, on your own box. Build the binary from github.com/RMS2D/omnomfeeds, or use the one-liner installers in the README. Pro-gated endpoints are open in self-host mode (you ARE the operator); the AI ones need ANTHROPIC_API_KEY or OPENAI_API_KEY in your env.