Get Stats (Aggregate)
Get combined statistics from multiple security data sources in a single request.
Endpoint
GET /api/v1/statsResponse
{
"success": true,
"data": {
"nix": {
"openIssues": 562,
"closedIssues": 2156,
"totalTracked": 2718,
"withFix": 2,
"assigned": 6,
"bySeverity": {
"critical": 0,
"high": 0,
"medium": 0,
"low": 0,
"unknown": 24
},
"oldestIssue": "2025-11-15T10:30:00.000Z",
"newestIssue": "2026-01-27T17:42:23.000Z"
},
"osv": {
"totalVulnerabilities": 567081,
"totalEcosystems": 38,
"topEcosystems": [
{ "name": "npm", "count": 214344 },
{ "name": "PyPI", "count": 17626 },
{ "name": "Maven", "count": 6135 }
]
},
"searchIndex": {
"available": true,
"advisories": 2144762,
"ecosystems": 38,
"ecosystemNames": ["npm", "PyPI", "Maven"],
"incompleteEcosystems": []
},
"last12h": {
"newAdvisories": 7,
"severityCounts": {
"critical": 2,
"high": 1,
"medium": 2,
"low": 2,
"unknown": 0
},
"latest": [
{
"ghsa_id": "GHSA-4486-gxhx-5mg7",
"severity": "medium",
"summary": "PsySH has Local Privilege Escalation via CWD .psysh.php auto-load",
"published_at": "2026-01-30T21:28:44Z"
}
]
}
},
"timestamp": "2026-01-30T12:00:00.000Z"
}nix, osv.totalVulnerabilities/osv.totalEcosystems and last12h.newAdvisories each read null, never a fabricated zero, when their own upstream source could not be read, live or from a recent backup. partial: true and failedSources (an array naming security_issues, osv_ecosystem_stats and/or recent_advisories) are added to the response, alongside success: true, whenever at least one of the three failed -- a caller checking only the top-level success flag is not told the response was complete when it was not. Both fields are omitted entirely when every source answered.
Response Fields
nix (nixpkgs security issues)
| Field | Type | Description |
|---|---|---|
openIssues | number | Open nixpkgs security issues. Every other figure in this block -- withFix, assigned, bySeverity, and the date range -- is over these, not over the whole corpus |
closedIssues | number | Tracked issues the project has resolved. Published so openIssues reads as a population rather than as a total |
totalTracked | number | openIssues + closedIssues, the whole corpus we hold |
withFix | number | Issues where a fixed version is available |
assigned | number | Issues assigned to a contributor |
bySeverity | object | Breakdown by severity (critical, high, medium, low, unknown) |
oldestIssue | string|null | ISO timestamp of the oldest open issue |
newestIssue | string|null | ISO timestamp of the newest open issue |
osv (OSV.dev Ecosystems)
| Field | Type | Description |
|---|---|---|
totalVulnerabilities | number | Total vulnerabilities across all ecosystems |
totalEcosystems | number | Number of supported ecosystems |
topEcosystems | array | Top 3 package manager ecosystems by vulnerability count |
searchIndex
| Field | Type | Description |
|---|---|---|
available | boolean | Whether the search index could be read for this response |
advisories | number | Advisories held in the search index |
ecosystems | number | Ecosystem count the index covers |
ecosystemNames | string[] | Ecosystem names the index covers |
incompleteEcosystems | string[] | Ecosystems whose index coverage is known to be partial |
last12h (Recent Advisories)
| Field | Type | Description |
|---|---|---|
newAdvisories | number | Advisories published in last 12 hours |
severityCounts | object | Breakdown by severity level |
latest | array | Up to 5 most recent advisories with id, severity, summary, and timestamp |
advisories | array | Every advisory in the window, not just the top 5 in latest |
countCapped | boolean | When true, more advisories existed than this response's fetch covered; counts are a floor |
latestBackfilled | boolean | Always false; kept for compatibility |
fetchedAt | string | ISO 8601 timestamp this window was fetched |
windowHours | number | The window this block covers (12) |
rejectedExcluded | boolean | Whether withdrawn/rejected advisories were filtered out before counting |
A last12h or searchIndex block that looks thin or empty should be read against countCapped/available before being read as "nothing happened" -- see Recent Advisories for the full contract these counts are drawn from.
Example
curl https://api.vulnpatch.dev/api/v1/statsCode Examples
async function displayStats() {
const response = await fetch('https://api.vulnpatch.dev/api/v1/stats');
const { data } = await response.json();
console.log(`Nix Issues: ${data.nix.openIssues}`);
console.log(`Total Vulnerabilities: ${data.osv.totalVulnerabilities.toLocaleString()}`);
console.log(`New (12h): ${data.last12h.newAdvisories}`);
console.log(`Critical (12h): ${data.last12h.severityCounts.critical}`);
// Show latest advisories
data.last12h.latest.forEach(adv => {
console.log(`[${adv.severity}] ${adv.summary}`);
});
}import requests
response = requests.get('https://api.vulnpatch.dev/api/v1/stats')
data = response.json()['data']
print(f"Nix Issues: {data['nix']['openIssues']}")
print(f"Total Vulnerabilities: {data['osv']['totalVulnerabilities']:,}")
print(f"New (12h): {data['last12h']['newAdvisories']}")
# Show latest advisories
for adv in data['last12h']['latest']:
print(f"[{adv['severity']}] {adv['summary']}")Use Cases
- Security dashboards: Display real-time vulnerability counts across ecosystems
- Landing pages: Show "X vulnerabilities tracked" stats
- Monitoring: Track vulnerability disclosure rates over time
- Alerting: Trigger alerts when critical CVEs spike
- News feeds: Show latest advisories from
last12h.latest
Related Endpoints
For more detailed data, use these endpoints:
/api/v1/nix/stats- Detailed nixpkgs security issue statistics/api/v1/ecosystem-stats- Full ecosystem breakdown/api/v1/recent-advisories- Recent advisory details
Caching
This endpoint is cached for 60 seconds. The X-Cache header indicates cache status.