Package Registries API & Scraper
The Package Registries API returns npm and PyPI package data as clean JSON.
🤖 Using an AI assistant? Copy this link into ChatGPT / Claude / Cursor — it reads every endpoint and parameter instantly and tells you if this API fits your use case.
The primary package endpoint returns a package's name, latest version, description, license, homepage, repository, keywords, maintainers and dependencies, and you can list versions, pull a specific version, resolve dependencies, read download stats, search and look up a maintainer. It is built for developer tools, dependency dashboards and supply-chain workflows that need normalized npm and PyPI metadata from one endpoint. One ReefAPI key, one shared credit pool, the standard envelope.
The same question, answered differently by npm and PyPI
One engine covers two registries, and they genuinely differ — not in our shaping, but in what each ecosystem publishes. registry is required on every action for that reason. Values below are measured from live calls on react, express and requests.
| What you want | npm returns | PyPI returns |
|---|---|---|
| the current version | the dist-tag resolution — measured react 19.2.8 | the project version |
| release channels | dist_tags with seven channels measured on react: latest, next, canary, experimental, beta, rc, backport | no equivalent — PyPI has no tag concept |
| dependencies | four separate maps: dependencies, dev_dependencies, peer_dependencies, optional_dependencies | requires_dist[] raw strings plus a parsed map |
| dependency values | semver RANGES, not pinned versions — measured express: qs "^6.14.0", cookie "^0.7.1" | PEP 508 specifiers, environment markers included |
| downloads | a count for the period you ask for, with start and end | three fixed windows at once — measured requests: last_day 42,760,091 · last_week 396,572,056 · last_month 1,804,395,908 |
| download source | the registry's own counts | pypistats.org, named in an attribution field you should carry with the number |
| per-version extras | dist and engines | requires_dist and classifiers |
version_count on the package action tells you how deep the history goes — measured 2,920 for react — and versions pages through it. Note that published_at came back null on every measured npm version row, because the abbreviated registry document that keeps a 2,920-version response fetchable omits the release-date map. The same is why the package action's time object came back empty.
Real request and response JSON
Captured from the indexed primary action, search, on .
{
"method": "POST",
"url": "https://api.reefapi.com/packages/v1/search",
"headers": {
"x-api-key": "$REEF_KEY",
"content-type": "application/json"
},
"body": {
"registry": "npm",
"query": "fastapi"
}
}{
"ok": true,
"meta": {
"api": "packages",
"endpoint": "search",
"mode": "live",
"latency_ms": 929.8,
"record_count": 20,
"bytes": 18608,
"cache_hit": false,
"registry": "npm",
"query": "fastapi",
"page": 1,
"page_size": 20,
"from": 0,
"next_from": 20,
"total": 1156,
"has_more": true
},
"data": {
"results": [
{
"registry": "npm",
"name": "fastapi",
"version": "0.0.8",
"description": "A simple CLI utility for quickly creating Express-based servers with a single configuration file",
"license": "ISC",
"keywords": [
"express",
"api",
"server"
],
"maintainers": [
{
"email": "[trimmed-depth]",
"username": "[trimmed-depth]"
}
],
"publisher": {
"email": "[redacted-email]",
"username": "timambler"
},
"date": "[redacted-phone]T16:12:09.755Z",
"links": {
"homepage": "https://github.com/tkambler/fastapi#readme",
"repository": "git+https://github.com/tkambler/fastapi.git",
"bugs": "https://github.com/tkambler/fastapi/issues",
"npm": "https://www.npmjs.com/package/fastapi"
},
"score": {
"final": 928.23816,
"detail": {
"popularity": "[trimmed-depth]",
"quality": "[trimmed-depth]",
"maintenance": "[trimmed-depth]"
}
},
"search_score": 928.23816,
"downloads": 2202,
"flags": {
"insecure": 0
}
},
{
"registry": "npm",
"name": "fastapi-rtk",
"version": "2.10.2",
"description": "A React component library for FastAPI in combination with FastAPI React Toolkit backend, built with Mantine, JsonForms, and Zustand.",
"license": "MIT",
"keywords": [
"fastapi",
"react",
"component"
],
"maintainers": [
{
"email": "[trimmed-depth]",
"username": "[trimmed-depth]"
}
],
"publisher": {
"email": "[redacted-email]",
"actor": {
"name": "[trimmed-depth]",
"type": "[trimmed-depth]",
"email": "[trimmed-depth]"
},
"username": "dtacs"
},
"date": "[redacted-phone]T12:54:47.152Z",
"links": {
"npm": "https://www.npmjs.com/package/fastapi-rtk"
},
"score": {
"final": 344.55225,
"detail": {
"popularity": "[trimmed-depth]",
"quality": "[trimmed-depth]",
"maintenance": "[trimmed-depth]"
}
},
"search_score": 344.55225,
"downloads": 6613,
"flags": {
"insecure": 0
}
},
{
"registry": "npm",
"name": "@kernlang/fastapi",
"version": "3.5.1",
"description": "Kern FastAPI Python backend transpiler",
"license": "AGPL-3.0",
"keywords": [
"kern",
"llm",
"fastapi"
],
"maintainers": [
{
"email": "[trimmed-depth]",
"username": "[trimmed-depth]"
}
],
"publisher": {
"email": "[redacted-email]",
"username": "cukasn"
},
"date": "[redacted-phone]T21:05:37.659Z",
"links": {
"npm": "https://www.npmjs.com/package/@kernlang/fastapi"
},
"score": {
"final": 255.54477,
"detail": {
"popularity": "[trimmed-depth]",
"quality": "[trimmed-depth]",
"maintenance": "[trimmed-depth]"
}
},
"search_score": 255.54477,
"downloads": 660,
"flags": {
"insecure": 0
}
}
]
}
}What the Package Registries API does
| Action | Description | Concrete use case | Key params |
|---|---|---|---|
| package | full package metadata (latest version normalized) | Platform and DevOps teams call package to get full package metadata (latest version normalized). | registry, name |
| versions | paginated version list for a package | Security and supply-chain teams call versions to get paginated version list for a package. | registry, name, page, page_size |
| version | single version metadata | Developer-tool builders call version to get single version metadata. | registry, name, version |
| dependencies | runtime + dev dependencies for a version (latest if omitted) | AI-agent developers call dependencies to get runtime + dev dependencies for a version (latest if omitted). | registry, name, version |
| downloads | download statistics (npm: period=last-day|week|month|year; pypi: recent day/week/month) | Platform and DevOps teams call downloads to get download statistics (npm. | registry, name, period |
| search | search packages (npm: registry API; pypi: libraries.io→HTML→ranked simple-index+enrich) | Security and supply-chain teams call search to search packages (npm. | registry, query, page, page_size, from |
| maintainer | maintainer/author records for a package | Developer-tool builders call maintainer to get maintainer/author records for a package. | registry, name |
Call search from your stack
curl -X POST https://api.reefapi.com/packages/v1/search \
-H "x-api-key: $REEF_KEY" \
-H "content-type: application/json" \
-d '{"registry":"npm","query":"fastapi"}'import requests
r = requests.post(
"https://api.reefapi.com/packages/v1/search",
headers={"x-api-key": REEF_KEY},
json={
"registry": "npm",
"query": "fastapi"
},
)
print(r.json()["data"])const res = await fetch("https://api.reefapi.com/packages/v1/search", {
method: "POST",
headers: {
"x-api-key": process.env.REEF_KEY,
"content-type": "application/json",
},
body: JSON.stringify({
"registry": "npm",
"query": "fastapi"
}),
});
const { ok, data, meta, error } = await res.json();Ask your MCP-connected assistant: call reefapi.packages.search with {"registry":"npm","query":"fastapi"}.Who uses this API and why
- Dependency dashboards call package and versions to track a library's releases and license.
- Supply-chain tools use dependencies to map a package's full dependency tree.
- Developer products use downloads and search to rank and compare packages by popularity.
Questions developers ask before integrating
Is the `latest` dist-tag the newest version?
No — it is the version npm install gives you, which is deliberately not the newest thing published. A measured react lookup returned latest 19.2.8 while the same dist_tags object carried canary at 19.3.0-canary-a1124489-20260826 and experimental at 0.0.0-experimental-a1124489-20260826, both newer builds. Seven channels came back on that one package: latest, next, canary, experimental, beta, rc and backport. If you are building an out-of-date check, compare against latest, not against the top of the versions list.
Are the dependency values actual versions I can install?
No, they are semver ranges exactly as the author wrote them. A measured express lookup returned qs "^6.14.0", cookie "^0.7.1" and body-parser "^2.2.1" — carets, not pins. Nothing here resolves a dependency tree or reads a lockfile, so what you get is the declared intent, not what a given install would produce. That is the right input for licence and policy checks on declared dependencies, and the wrong input for reconstructing a specific build.
A package returned an empty dependencies object. Is that a fetch failure?
Usually not. Measured, react returned dependencies {} and dev_dependencies {} because it genuinely ships with no runtime dependencies — while express, fetched the same way, returned 28 runtime and 16 dev dependencies. An empty map is a real answer about the package. Cross-check with the dependencies action, which returns the four maps for a specific version, before you conclude anything went wrong.
Why do download numbers come back in a different shape per registry?
Because the two ecosystems publish different things. For PyPI you get last_day, last_week and last_month together in one response — measured on requests as 42.8 million, 396.6 million and 1.8 billion — sourced from pypistats.org and carrying an attribution string you are expected to keep with the figure. For npm you ask for a period and get a single count with its start and end dates. Do not build one chart that mixes the two without normalizing the window first.
Why is published_at null on version rows?
Because the registry document being read is the abbreviated one, which omits release dates. A measured versions call on react returned 2,920 total versions with published_at null on every row, and meta reported fetch_mode "abbreviated" so the reason is visible rather than hidden. The same omission is why the package action's time object came back as {}. Version strings, ordering and the latest flag are all present and reliable; dates are the thing to get elsewhere if you need them.
How do I page through a package with thousands of versions?
versions takes page and page_size, and meta returns page, page_size, total, has_more and next_page. Measured on react, total came back as 2,920 — a package with that much history is not something to pull in one call, and pre-release channels dominate the top of the list. If you only want stable releases, filter the version strings yourself: anything carrying canary, experimental, beta or rc in the string is a pre-release by npm convention.
Do I need registry credentials?
No. Both npm and PyPI publish this metadata openly, and neither needs an account, a token, or a rate-limit deal — you use your ReefAPI key and nothing else. That is the whole point of routing it through here: one key and one response envelope across two registries that otherwise have different hosts, different auth stories and different JSON shapes.
Can I search for packages rather than look one up?
Yes — search takes the registry plus a query and returns name, version, description, license, a relevance score and links or maintainers per hit, with paging in meta. The score is the registry's own relevance ranking, not a quality or popularity metric, so do not present it as one. If you want popularity, take the names from search and follow up with downloads.
What is the Package Registries API?
Package Registries API is a ReefAPI endpoint group for package registries It returns live JSON through POST requests under /packages/v1.
Is the Package Registries API free to try?
Yes. ReefAPI starts with 1,000 free credits, no card required. Package Registries calls use the same shared credit balance as every other ReefAPI engine.
Do I need a Package Registries login or account?
No login to Package Registries is needed for the API response. You call ReefAPI with your x-api-key header, and the playground can run live examples before you create a production key.
How fresh is the Package Registries data?
The page example is captured from a live package call, and production requests fetch live data through ReefAPI rather than a static sample.
How many credits does the Package Registries API use?
Package Registries actions currently cost 1-2 credits per successful call. Failed or blocked calls are free, and all APIs draw from one credit pool.
Can I call Package Registries from an AI assistant or MCP client?
Yes. Connect ReefAPI once through MCP and your assistant can call packages actions with the same key, credit pool and JSON envelope used by normal REST requests.