API docs
Everything on ziro.sh is static and public. No key and no account: fetch the file. Every JSON response uses the same envelope so a client can pin the schema version.
{ "schema_version": 1, "generated_at": "2026-10-25T00:00:00.000Z", "data": [] }
Endpoints
| Path | Returns |
|---|---|
/feed.json |
Records from the last 30 days, newest first |
/records.json |
Every published record |
/cve/{id}.json |
One record by CVE or incident id |
/week/{yyyy-ww}.json |
One ISO week of records |
/schema/record.v1.json |
JSON Schema for a record |
/openapi.json |
OpenAPI 3.1 description of these endpoints |
/rss.xml |
RSS 2.0, last 30 days |
/llms.txt |
Index for language models |
Quick start
curl -s https://ziro.sh/feed.json | jq '.data[] | {id, affects}'
Match affects[].ranges against your lockfile. Ranges use OSV and semver comparators, for example >=8.4.0 <8.4.27, and fixed lists the first safe version on each release line. Pick the smallest one above your installed version; jumping to the highest can mean a breaking major upgrade you don’t need.
Markdown for agents
Every page answers Accept: text/markdown with a Markdown version of itself, served with Vary: Accept. Record and week pages also answer Accept: application/json with their JSON twin.
curl -s -H 'Accept: text/markdown' https://ziro.sh/
Record fields
| Field | Meaning |
|---|---|
id |
CVE id, or a ziro incident id for events without one |
kind |
cve or incident |
severity |
cvss, epss (0 to 1) and kev (in CISA KEV) |
affects |
Per package: ecosystem, package, ranges, fixed |
exploited_since, disclosed |
ISO dates, or null when unknown |
summary |
Two human-reviewed sentences |
sources |
At least two links the record is based on |
review |
Who published it and when |
Empty beats guessed: a field the sources do not agree on is left null.
MCP
An MCP server with latest, get_cve and affects tools is planned. It is not live yet; this page will list its URL when it is.
When it is, affects will return one match per affected package with:
| Field | Meaning |
|---|---|
fix |
Smallest safe upgrade: the lowest fixed version above what you have installed |
fix_breaking |
true when fix crosses a major version (or a minor on 0.x); null when there is no fix |
latest_fix |
Highest fixed version the record lists. Often a bigger jump than you need |
uncertain |
true when your version couldn’t be compared; check it by hand |
Upgrade to fix, not latest_fix, unless you want the major bump anyway. Records list one fixed version per release line, so fix usually stays on your current major.
Errors
Unknown paths return a real 404. JSON paths, /api/* and requests that ask for JSON get RFC 9457 problem details with a stable code:
{
"type": "https://ziro.sh/docs#errors",
"title": "Not found",
"status": 404,
"code": "not_found",
"detail": "Nothing is published at /cve/CVE-1999-0001.json."
}
Markdown requests get a Markdown 404 and browsers get an HTML one. Anything other than GET, HEAD or OPTIONS returns 405 with code: "method_not_allowed".
Versioning
Every response carries schema_version. It changes only for a breaking change, such as a renamed or removed field; new optional fields do not bump it. A breaking change is announced on this page before it ships, and the previous version keeps being served alongside it for at least 30 days.