Skip to content

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/:package

The path is under /nix/. An earlier edition of this page named /api/v1/repology/:package, which has never answered.

Path Parameters ​

ParameterTypeRequiredDescription
packagestringYesPackage 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 ​

json
{
  "success": true,
  "data": {
    "found": true,
    "package": "curl",
    "normalizedName": "curl",
    "versions": {
      "nixos-26.05": { "version": "8.22.0", "status": "newest", "vulnerable": null },
      "nixpkgs-unstable": { "version": "8.22.0", "status": "newest", "vulnerable": null },
      "nixos-25.11": { "version": "8.20.0", "status": "outdated", "vulnerable": null }
    },
    "newestVersion": "8.22.0",
    "newestRepo": "aerynos",
    "fromMirror": true,
    "repologyUrl": "https://repology.org/project/curl/versions"
  },
  "timestamp": "2026-09-28T01:02:54.539Z"
}

Response Fields ​

FieldTypeDescription
foundbooleanWhether Repology knows the project. false with success: true is a checked negative.
packagestringThe name asked for
normalizedNamestringThe name after nixpkgs-style normalisation
matchedNamestringPresent when the exact name missed and an unversioned project answered instead
exactNameMatchbooleanPresent with matchedName; false when the fallback was used
versionsobjectKeyed by Repology repository name: nixpkgs-unstable and each nixos-<series>
versions.<repo>.versionstring|nullThe version that repository carries. null when identityUnresolved is true -- a confirmed-wrong version is withheld rather than served
versions.<repo>.statusstring|nullRepology's status for it: newest, outdated, devel, unique, legacy. null alongside a withheld version
versions.<repo>.vulnerableboolean|nullRepology's own vulnerability flag for that version, when Repology sent one. null whenever Repology sent no flag for that row (most rows) or alongside a withheld version -- never a fabricated false
versions.<repo>.ambiguousPackagesnumberPresent, and greater than 1, only when fromMirror is true and this repository ships more than one distinct binary package for the project: the mirror keeps one row per project per repository
versions.<repo>.identityUnresolvedbooleanPresent and true only when the mirror's kept row is confirmed, by its own recorded source-package name, to belong to a different binary package than the one asked about -- wget2's row kept under the wget project, say. version/status/vulnerable are withheld rather than reported, since they would be a confident wrong answer. ambiguousPackages > 1 with no identityUnresolved means a collision exists but the kept row's name was not recorded as differing, so it is not withheld
newestVersionstring|nullThe newest version any tracked repository carries
newestRepostring|nullWhich repository carries it
fromMirrorbooleanTrue when the answer came from this service's copy of Repology rather than from Repology. Those are different claims about freshness.
repologyUrlstringThe 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.

json
{
  "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 ​

bash
curl "https://api.vulnpatch.dev/api/v1/nix/repology/curl"
curl "https://api.vulnpatch.dev/api/v1/nix/repology/openssl"

Code Examples ​

javascript
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})`);
  }
}
python
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.