Skip to main content
Tutorial

Package Registry APIs: npm, PyPI, crates.io in One Key

Query npm, PyPI, crates.io, RubyGems, NuGet and endoflife.date from one API: versions, downloads, advisories and support dates for agents.

fastcrw
By RecepNovember 12, 20267 min read

By the fastCRW team · Catalogue figures checked 2026-11-05 against GET /v1/data · Verify independently before relying on any figure.

A coding agent that checks a dependency needs the same facts a human does: the latest version, how many people install it, whether the maintainers still ship releases, and when the runtime underneath it stops getting security fixes. Each package registry answers those questions in its own shape. npm, PyPI, crates.io, RubyGems, NuGet and endoflife.date are all callable through one API key in fastCRW's Pergamon catalogue. This guide shows the calls we ran on 2026-11-05 and the output they returned. The pillar post covers the catalogue itself, and Claude Code with fastCRW shows how a coding agent gets set up.

One call per registry

Each registry has its own capability for metadata, versions and downloads. The table below lists the call an agent makes first. Each capability takes the package name or identifier as an option, and each response carries its provenance block.

RegistryCapability for metadataOption
npmnpm/packagepackage
PyPIpypi/projectname
crates.iocrates/cratename
RubyGemsrubygems/gemname
NuGetnuget/packagename (lower-case id)

Downloads from npm

npm reports downloads over a period. Use last-week for the most recent week, and name the package. This call returns the total for one week.

curl "https://api.fastcrw.com/v1/data/npm/downloads-point?period=last-week&package=react" \
  -H "Authorization: Bearer $CRW_API_KEY"

Our run returned a single data object with downloads, start, end and package. For react, the week from 2026-10-28 to 2026-11-03 returned 246988547 downloads. The number moves every week, so store the start and end dates with it.

PyPI, crates.io and RubyGems

The three registries that serve metadata directly return their own JSON. The SDK call below runs the metadata lookups for requests, serde and rails in one script. Each call is billed at the creditsCost its capability lists.

# pip install crw
from crw import CrwClient

client = CrwClient()  # reads CRW_API_KEY

pypi = client.get_data("pypi", "project", {"name": "requests"})
crate = client.get_data("crates", "crate", {"name": "serde"})
gem = client.get_data("rubygems", "gem", {"name": "rails"})

print(pypi["data"]["info"]["name"], pypi["data"]["info"]["version"])
print(crate["data"]["crate"]["name"], crate["data"]["crate"]["max_version"])
print(gem["data"]["name"], gem["data"]["version"])

Output from that run:

requests 2.34.2
serde 1.0.229
rails 8.1.4.1

Support windows with endoflife.date

A package can be current and still sit on a runtime that no longer gets fixes. endoflife.date tracks support windows per product and cycle. This call asks for Python 3.9.

curl "https://api.fastcrw.com/v1/data/endoflife/cycle?product=python&cycle=3.9" \
  -H "Authorization: Bearer $CRW_API_KEY"

Our run returned releaseDate 2020-10-05, eol 2025-10-31, latest 3.9.25 and lts false. The end-of-life date had already passed on 2026-11-05, so an agent can flag the runtime without any judgement of its own.

Cross-ecosystem view with deps.dev

deps.dev covers several ecosystems with one schema. The version call takes the system, the name and the version. For a specific npm version, it returns the advisory keys, the licences and the deprecation state in one response.

curl "https://api.fastcrw.com/v1/data/depsdev/version?system=npm&name=react&version=18.2.0" \
  -H "Authorization: Bearer $CRW_API_KEY"

The keys in the response include advisoryKeys, licenses, isDeprecated, publishedAt and registries. The advisory keys are identifiers, not descriptions: look each one up in the OSV source rather than trusting a count. Use depsdev/version in agents. The package-level depsdev/package response for react is about 566 KB and lists about 3,000 versions.

NuGet from the same key

NuGet publishes its registration index in pages, grouped by version range. One call names the package, and the response is the index the NuGet V3 API serves.

curl "https://api.fastcrw.com/v1/data/nuget/package?name=newtonsoft.json" \
  -H "Authorization: Bearer $CRW_API_KEY"

Read the items array page by page. Do not assume the first page is the newest release.

From an agent

Through MCP the agent finds the registry capability first, then calls it. The find call is free, and the get call carries the options.

{"name": "crw_find_data", "arguments": {"query": "package registry metadata", "category": "Developer", "limit": 10}}
{"name": "crw_get_data", "arguments": {"provider": "endoflife", "capability": "cycle", "options": {"product": "python", "cycle": "3.9"}}}

The question an agent should answer is simple: is this dependency maintained? Combine the latest version date from the registry, the download count, and the runtime's support window. Report each fact with its source, and say when a registry returned nothing.

Which call answers which question

Start from the question, then pick the registry that owns the answer. The mapping below is the one this guide uses.

  • Is the latest release recent? Use the registry's metadata call and read its newest version and release date.
  • Is the package widely used? Use npm downloads for a period. Other registries in the catalogue return their own counts, so compare within one registry, not across them.
  • Is the runtime still supported? Use endoflife.date for the product and cycle your project targets.
  • Does a version carry known advisories? Use deps.dev for the advisory keys, then look each one up in the OSV provider.

The catalogue also lists Packagist and Hex, so PHP and Elixir projects can use the same pattern. Hex, Maven Central and Hugging Face run on your own machine, so they need the local install.

Is this dependency maintained?

Put the registry and the support window together and an agent can answer the question with dates. This script ran unchanged on 2026-11-05. It reads the upload time of the newest requests release from PyPI and the end-of-life date of Python 3.9.

# pip install crw
from crw import CrwClient

client = CrwClient()  # reads CRW_API_KEY

pypi = client.get_data("pypi", "project", {"name": "requests"})
latest = pypi["data"]["urls"][0]["upload_time_iso_8601"]
python = client.get_data("endoflife", "cycle", {"product": "python", "cycle": "3.9"})

print("requests", pypi["data"]["info"]["version"], "uploaded", latest[:10])
print("python 3.9 eol", python["data"]["eol"])
requests 2.34.2 uploaded 2026-05-14
python 3.9 eol 2025-10-31

The agent can now say that the newest release is about six months old and that the runtime it targets is past its end-of-life date, and cite both calls. It should not say the project is abandoned. A release date is one signal. Open issues, maintainers and a changelog are others, and none of them come from these capabilities.

Response size and the MCP cap

REST and the SDK return the whole upstream body. MCP results over 256 KiB are refused with result_too_large and refunded for server sources. Large package documents are the usual case, which is why the agent path above uses the version-level deps.dev call. Check the size of any capability before you put it in an agent loop.

Licences

Each registry's terms ride along in provenance.licence. From the catalogue rows: npm says "You may replicate data from the Public Registry using the Public APIs per this Agreement." deps.dev says "This generated data is available under a CC-BY 4.0 license." For crates.io, RubyGems and NuGet the rows say the metadata is passed through and that the catalogue does "not licence callers to rebuild the registry". endoflife.date descriptions are adapted from Wikipedia under CC BY-SA 3.0, "so a derived work carries the same share-alike obligation". Quote the line that came back, and do not treat any of this as a blanket permission to mirror a registry.

Limits

  • The calls in this guide do not return a dependents count. crates.io and RubyGems list separate reverse-dependencies capabilities, which this guide did not run.
  • Download counts are the registry's own numbers and are reported over a period. Compare periods of the same length.
  • Some registries and some ecosystems are client-run on your machine. Check the execution field before you assume a server call.

Keep the provenance with the number

Every answer about a package should show where its numbers came from. REST returns provenance.upstream_url, provenance.licence and provenance.retrieved_at. The SDK returns the same facts as upstreamUrl, licence and retrievedAt. Store them with the figure, because a download count or a support date means little without the day it was read.

Cost

Find and catalogue calls are free. Server calls cost the creditsCost listed on each capability, usually 1 credit, and a failed call is not billed. Plan prices are on the pricing page.

Sources

Related: Public data API for AI agents · MCP server for public data · CVE API for AI agents · Pergamon catalogue

FAQ

Frequently asked questions

Does the catalogue give me reverse dependencies for a package?
Not from the calls in this guide, which return a package's own metadata, versions and downloads. crates.io and RubyGems list separate reverse-dependencies capabilities. Run find with the registry as provider to see them before you rely on one.
Why is the npm download count for last-week not a fixed number?
The count changes every week because the registry publishes new download totals. Store the start and end dates with the number so each figure can be read in context.
Can an agent check a whole lockfile this way?
Yes, one call per package, plus the advisory and support checks. Cap the number of calls per run, because each server call is billed at its creditsCost.

Get Started

Try fastCRW free

Run a live request in the playground — no signup required. Or grab a free API key with 500 credits, earn up to 500 more, no credit card.

Continue exploring

More tutorial posts

View category archive