Repology Lookup
The versions each nixpkgs channel carries for a package, and the newest version any repository Repology tracks has, read from Repology or from this service's own mirror of it.
Endpoint
GET /api/v1/nix/repology/:packageThe path is under /nix/. An earlier edition of this page named /api/v1/repology/:package, which has never answered.
Path Parameters
| Parameter | Type | Required | Description |
|---|---|---|---|
package | string | Yes | Package name, drawn from letters, digits, ., -, _ and /. |
nixpkgs versions its attribute names and Repology does not, so a miss on the exact name falls back to the unversioned project: openssl_3 to openssl, python3 to python. When that happens the response carries matchedName and exactNameMatch: false, because being told about python while believing you asked about python3 is a useful answer and a dangerous one. A bare trailing digit is only stripped for names on an explicit list: log4j2 is its own project rather than a version of log4j.
Response
{
"success": true,
"data": {
"found": true,
"package": "curl",
"normalizedName": "curl",
"versions": {
"nixos-26.05": { "version": "8.22.0", "status": "newest", "vulnerable": false },
"nixpkgs-unstable": { "version": "8.22.0", "status": "newest", "vulnerable": false },
"nixos-25.11": { "version": "8.20.0", "status": "outdated", "vulnerable": false }
},
"newestVersion": "8.22.0",
"newestRepo": "aerynos",
"fromMirror": true,
"repologyUrl": "https://repology.org/project/curl/versions"
},
"timestamp": "2026-09-28T01:02:54.539Z"
}Response Fields
| Field | Type | Description |
|---|---|---|
found | boolean | Whether Repology knows the project. false with success: true is a checked negative. |
package | string | The name asked for |
normalizedName | string | The name after nixpkgs-style normalisation |
matchedName | string | Present when the exact name missed and an unversioned project answered instead |
exactNameMatch | boolean | Present with matchedName; false when the fallback was used |
versions | object | Keyed by Repology repository name: nixpkgs-unstable and each nixos-<series> |
versions.<repo>.version | string | The version that repository carries |
versions.<repo>.status | string | Repology's status for it: newest, outdated, devel, unique, legacy |
versions.<repo>.vulnerable | boolean | Repology's own vulnerability flag for that version |
newestVersion | string|null | The newest version any tracked repository carries |
newestRepo | string|null | Which repository carries it |
fromMirror | boolean | True when the answer came from this service's copy of Repology rather than from Repology. Those are different claims about freshness. |
repologyUrl | string | The project page on Repology |
When Repology cannot be read
An upstream failure answers 200 with success: false, degraded: true and data.found: false, cached for five minutes so retries do not hammer Repology. found: false there means the lookup failed, not that Repology lacks the package; read success and degraded before found.
{
"success": false,
"degraded": true,
"data": { "found": false, "package": "curl", "error": "Upstream service unavailable", "versions": {} },
"timestamp": "2026-09-28T01:02:54.539Z"
}A name with characters package names never carry answers 400.
Examples
curl "https://api.vulnpatch.dev/api/v1/nix/repology/curl"
curl "https://api.vulnpatch.dev/api/v1/nix/repology/openssl"Code Examples
async function checkPackageVersion(packageName) {
const response = await fetch(
`https://api.vulnpatch.dev/api/v1/nix/repology/${packageName}`
);
const body = await response.json();
if (!body.success) {
console.log(`Repology could not be read: ${body.data.error}`);
return;
}
if (!body.data.found) {
console.log(`Repology does not know ${packageName}`);
return;
}
console.log(`Newest anywhere: ${body.data.newestVersion} (${body.data.newestRepo})`);
const unstable = body.data.versions['nixpkgs-unstable'];
if (unstable) {
console.log(`nixpkgs-unstable: ${unstable.version} (${unstable.status})`);
}
}import requests
def check_package_version(package_name):
response = requests.get(
f'https://api.vulnpatch.dev/api/v1/nix/repology/{package_name}'
)
body = response.json()
if not body['success']:
print(f"Repology could not be read: {body['data']['error']}")
return
if not body['data']['found']:
print(f"Repology does not know {package_name}")
return
data = body['data']
print(f"Newest anywhere: {data['newestVersion']} ({data['newestRepo']})")
unstable = data['versions'].get('nixpkgs-unstable')
if unstable:
print(f"nixpkgs-unstable: {unstable['version']} ({unstable['status']})")Caching
Answers are cached for two hours; failures for five minutes. The X-Cache header says which you received.
Related Endpoints
- NixOS channels and builds - which channels exist and what Hydra built
- CVE Matching - CVEs matched against the versions nixpkgs carries