NuGet Package Scraper: .NET Packages & Frameworks avatar

NuGet Package Scraper: .NET Packages & Frameworks

Pricing

from $0.37 / 1,000 package scrapeds

Go to Apify Store
NuGet Package Scraper: .NET Packages & Frameworks

NuGet Package Scraper: .NET Packages & Frameworks

Extract NuGet registration data: versions, dependency groups by target framework, licence, authors, deprecation and vulnerability notices. No key, no proxy.

Pricing

from $0.37 / 1,000 package scrapeds

Rating

0.0

(0)

Developer

Arman Hossain

Arman Hossain

Maintained by Community

Actor stats

0

Bookmarked

1

Total users

0

Monthly active users

19 days ago

Last modified

Share

NuGet Package Scraper: Every version, per-framework dependency groups, licence, deprecation notices and vulnerability advisories for any NuGet package

Reads registration data straight from the official nuget.org V3 API: every version, dependency groups broken out per target framework, licence expression, authors, publish dates, deprecation notices with their replacement package, and vulnerability advisories.

It talks to api.nuget.org over plain HTTP, so there's no credentials, no login, no proxy and no browser. A latest-version lookup costs two requests per package however many hundreds of versions that package has.

Agent skill: SKILL.md

https://api.apify.com/v2/key-value-stores/t7YoTxpZEJOWvw4Ug/records/nuget-package-scraper.md

What you get

FieldWhat it holds
id, latestVersion, urlPackage ID as NuGet cases it, the resolved latest version, and the nuget.org page
description, summary, title, tagsDescriptive metadata from the catalogue entry
authorsAuthor list, split from NuGet's comma-separated string
licenseExpression, licenseUrl, projectUrl, iconUrlSPDX licence expression and project links
dependencyGroups[{ targetFramework, dependencies: [{ id, range }] }] for the latest version
targetFrameworksEvery TFM the latest version declares a dependency group for
dependencyCountTotal dependencies across all returned groups
isDeprecated, deprecationReasons, deprecationMessage, alternatePackageDeprecation state and the package NuGet recommends instead
vulnerabilities[{ advisoryUrl, severity }] where nuget.org has advisories
isListed, publishedWhether the latest version is listed, and when it was published
totalVersionsEvery version ever pushed, prerelease included
versionsPer-version array with publish date, listed flag, deprecation flag and TFMs (opt-in)
packageContentDirect .nupkg URL
scrapedAtRun timestamp

RUN_SUMMARY in the key-value store holds per-run counts, the flags you used, and any package that failed.

Use cases

  • Dependency audits. Licence expression, deprecation state and advisories arrive in one row per package.
  • Framework compatibility. targetFramework: "net8.0" shows exactly what a package needs on that TFM.
  • Replacing dead packages. alternatePackage is NuGet's own recommendation, not a guess.
  • Microsoft-stack tracking. Publish dates and version counts across a portfolio of packages.
  • SBOM pipelines. Flat JSON that joins cleanly against your .csproj package references.

Quick start

Two packages, latest stable only:

{
"packages": ["Newtonsoft.Json", "Serilog"]
}

What a package needs on .NET 8 specifically:

{
"packages": ["Serilog", "Dapper", "Microsoft.Extensions.Logging"],
"targetFramework": "net8.0"
}

Full history including prereleases, for a release-cadence study:

{
"packages": ["https://www.nuget.org/packages/Serilog"],
"includeAllVersions": true,
"includePrerelease": true
}

Input

FieldTypeDefaultNotes
packagesarrayrequiredPackage IDs, case-insensitive, or full nuget.org package URLs. Duplicates are removed.
includeAllVersionsbooleanfalseAdds the versions array. Walks every registration page, so Serilog costs ten extra requests.
includePrereleasebooleanfalseLets prereleases win latestVersion and keeps them in versions.
targetFrameworkstring""Case-insensitive exact match on a TFM, such as net8.0, netstandard2.0 or .NETFramework4.7.1.

totalVersions is always the true total even with includeAllVersions off, because NuGet publishes a per-page leaf count in the registration index. The targetFramework filter narrows dependencyGroups, targetFrameworks and dependencyCount; a package with no group for that TFM comes back with all three empty, which is itself the answer to "does this support net8.0?".

Output example

A real record for Serilog, dependency groups truncated to three:

{
"id": "Serilog",
"latestVersion": "4.4.0",
"description": "Simple .NET logging with fully-structured events",
"summary": null,
"title": null,
"authors": ["Serilog Contributors"],
"licenseExpression": "Apache-2.0",
"licenseUrl": "https://www.nuget.org/packages/Serilog/4.4.0/license",
"projectUrl": "https://serilog.net/",
"iconUrl": "https://api.nuget.org/v3-flatcontainer/serilog/4.4.0/icon",
"tags": ["serilog", "logging", "semantic", "structured"],
"dependencyGroups": [
{ "targetFramework": "net10.0", "dependencies": [] },
{
"targetFramework": ".NETFramework4.6.2",
"dependencies": [
{ "id": "System.Diagnostics.DiagnosticSource", "range": "[8.0.1, )" },
{ "id": "System.Threading.Channels", "range": "[8.0.0, )" },
{ "id": "System.ValueTuple", "range": "[4.5.0, )" }
]
}
],
"targetFrameworks": ["net10.0", ".NETFramework4.6.2", ".NETFramework4.7.1", "net6.0", "net8.0", "net9.0", ".NETStandard2.0"],
"dependencyCount": 7,
"isDeprecated": false,
"deprecationReasons": [],
"deprecationMessage": null,
"alternatePackage": null,
"vulnerabilities": [],
"isListed": true,
"published": "2026-07-10T03:35:24.047+00:00",
"totalVersions": 600,
"versions": [],
"packageContent": "https://api.nuget.org/v3-flatcontainer/serilog/4.4.0/serilog.4.4.0.nupkg",
"url": "https://www.nuget.org/packages/Serilog",
"scrapedAt": "2026-08-06T11:45:24.979Z"
}

A deprecated package fills in the fields that matter for an audit. WindowsAzure.Storage returns isDeprecated: true, deprecationReasons: ["Legacy"], the full maintainer message, and alternatePackage: "Azure.Storage.Common".

Naming a package

What you haveWhat to pass
Newtonsoft.JsonNewtonsoft.Json
newtonsoft.jsoneither one, since the registration path is lowercased for you
https://www.nuget.org/packages/Dappereither the URL or Dapper

The id field in the output uses NuGet's own casing, not yours, so it joins cleanly against .csproj references.

API example

curl -X POST "https://api.apify.com/v2/acts/arman-bd~nuget-package-scraper/run-sync-get-dataset-items?token=YOUR_TOKEN" \
-H "Content-Type: application/json" \
-d '{
"packages": ["Newtonsoft.Json", "Serilog"],
"targetFramework": "net8.0"
}'

JavaScript example

import { ApifyClient } from 'apify-client';
const client = new ApifyClient({ token: 'YOUR_TOKEN' });
const run = await client.actor('arman-bd/nuget-package-scraper').call({
packages: ['Newtonsoft.Json', 'Serilog', 'Dapper'],
targetFramework: 'net8.0',
});
const { items } = await client.dataset(run.defaultDatasetId).listItems();
for (const p of items) {
const flag = p.isDeprecated ? ` (DEPRECATED, use ${p.alternatePackage})` : '';
console.log(`${p.id}@${p.latestVersion} [${p.licenseExpression}]${flag}`);
}

Limits and behaviour

  • This uses registration5-gz-semver2, not registration5-semver1. The older feed omits deprecation and vulnerabilities entirely. The gzipped semver2 feed is the RegistrationsBaseUrl/3.6.0 resource advertised in nuget.org's own service index, and it is the only one that can answer an audit question.
  • Registration pages are not always inlined. Small packages inline their version leaves in the index, while large ones return only page stubs with an @id to follow, and Serilog has ten such pages. The Actor detects both and fetches only what it needs.
  • Latest-version lookups are cheap. With includeAllVersions off, the Actor walks pages newest first and stops at the first page containing a matching version, which is usually one index plus one page whatever the package size.
  • Versions are sorted with a real SemVer 2 comparator, so 4.4.0 outranks 4.10.0-beta and a prerelease never outranks its own release.
  • A missing package won't kill the run. nuget.org serves registrations from blob storage, so an unknown ID is an XML 404; it lands in RUN_SUMMARY.failures and the run continues. The Actor errors out only if every package failed.
  • Transient errors get retried. 429s and 5xx responses get three attempts with linear backoff. A 404 is fatal for that package.
  • Public data only. No authentication, no private feeds, no personal data.

FAQ

Do I need a proxy? No. Proxy configuration is not required to run this Actor.

Do I need a NuGet account or API key? No. You supply no credentials.

Are package IDs case-sensitive? Not for input, because the registration path is lowercased for you. The output id carries NuGet's canonical casing.

Why does a package show no dependency groups? Either it declares none, or your targetFramework filter matched nothing. Drop the filter and check targetFrameworks to see what it actually supports.

Why is vulnerabilities usually empty? NuGet attaches advisories to specific affected versions, and most current releases have none. The field reflects what the registration feed carries for the version returned; it is never inferred.

Can I read private or self-hosted feeds? No. This Actor targets nuget.org only.

Can I plug it into something else? Yes. Apify API, the client libraries, webhooks, scheduled runs, dataset exports to JSON, CSV or Excel, or MCP. The output is structured JSON.