# npm + PyPI Package Release & Supply-Chain Monitor (`produkdigitalali/npm-pypi-release-supply-chain-monitor`) Actor

Monitor npm and PyPI packages for new releases, dependency changes, maintainer changes, license changes, deprecations, yanked releases, artifact hashes, provenance, and download shifts. Built for dependency tracking, software supply-chain monitoring, DevOps, security, and automated alerts.

- **URL**: https://apify.com/produkdigitalali/npm-pypi-release-supply-chain-monitor.md
- **Developed by:** [ProdukDigitalAli](https://apify.com/produkdigitalali) (community)
- **Categories:**
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 package processeds

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.

Learn more: https://docs.apify.com/actors/running/actors-in-store.md#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
In Batch mode, an Actor accepts a well-defined JSON input, performs an action which can take anything from a few seconds to a few hours,
and optionally produces a well-defined JSON output, datasets with results, or files in key-value store.
In Standby mode, an Actor provides a web server which can be used as a website, API, or an MCP server.
Actors are written with capital "A".

## How to integrate an Actor?

If asked about integration, you help developers integrate Actors into their projects.
You adapt to their stack and deliver integrations that are safe, well-documented, and production-ready.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## npm + PyPI Package Release & Supply-Chain Monitor

Track public npm and PyPI package releases, dependencies, maintainers, licenses, artifact hashes, deprecations/yanks, and meaningful changes across scheduled runs.

This Actor is designed for developer tooling, dependency intelligence, release watching, CI/CD automation, software supply-chain monitoring, and AI-agent workflows. It uses public JSON registry endpoints only: **no browser, no API key, and no proxy are required**.

### What it monitors

For each npm or PyPI package, the Actor produces a normalized `PACKAGE_SNAPSHOT` with:

- registry-qualified stable package identity;
- latest version and release timestamp;
- description, license, author, maintainers/publisher;
- homepage, repository, and project URLs;
- npm runtime / optional / peer dependencies;
- PyPI `requires_dist` and `requires_python`;
- bounded newest-first release history;
- latest npm tarball integrity/shasum/signature-key metadata;
- latest PyPI distribution SHA-256 / BLAKE2b / MD5 hashes and yank state;
- npm public download counts for last day, week, or month;
- deterministic metadata, dependencies, maintainers, artifact, and supply-chain snapshot hashes.

When monitoring is enabled, state is persisted across runs and the Actor emits deterministic `CHANGE` records.

### Change types

- `NEW` — first observed package baseline.
- `UNCHANGED` — monitored supply-chain state did not change.
- `NEW_VERSION` — latest version changed.
- `DEPENDENCY_CHANGED` — normalized dependency state changed.
- `MAINTAINER_CHANGED` — normalized maintainer state changed.
- `LICENSE_CHANGED` — license changed.
- `DEPRECATED` / `DEPRECATION_REMOVED` — npm latest-version deprecation state changed.
- `YANKED` / `UNYANKED` — current PyPI release yank state changed.
- `ARTIFACT_CHANGED` — hashes/artifact metadata changed without a latest-version change.
- `DOWNLOAD_SPIKE` / `DOWNLOAD_DROP` — npm download count changed beyond the configured percentage threshold.
- `METADATA_CHANGED` — other normalized metadata changed when no more specific supply-chain change explains it.

### Example input

```json
{
  "npmPackages": [
    "react",
    "typescript",
    "@types/node"
  ],
  "pypiPackages": [
    "fastapi",
    "pydantic",
    "httpx"
  ],
  "maxPackages": 50,
  "includeDependencies": true,
  "includeReleaseHistory": true,
  "maxReleaseHistory": 20,
  "includeDownloadStats": true,
  "downloadPeriod": "last-week",
  "monitorMode": true,
  "emitChangesOnly": false,
  "baselineOnly": false,
  "monitorKey": "production-dependencies",
  "downloadChangeThresholdPercent": 50,
  "concurrency": 10,
  "requestTimeoutSeconds": 20,
  "maxRetries": 2
}
```

### Example package snapshot

```json
{
  "recordType": "PACKAGE_SNAPSHOT",
  "status": "SUCCESS",
  "registry": "npm",
  "packageName": "react",
  "packageKey": "npm:react",
  "latestVersion": "19.x.x",
  "license": "MIT",
  "deprecated": false,
  "dependencyCount": 0,
  "downloadStats": {
    "period": "last-week",
    "downloads": 12345678,
    "start": "2026-08-17",
    "end": "2026-08-23"
  },
  "snapshotHash": "...",
  "checkedAt": "2026-08-29T00:00:00Z"
}
```

### Example change record

```json
{
  "recordType": "CHANGE",
  "status": "SUCCESS",
  "registry": "pypi",
  "packageName": "fastapi",
  "packageKey": "pypi:fastapi",
  "latestVersion": "0.x.x",
  "changeType": "NEW_VERSION",
  "previousValue": "0.x.x",
  "currentValue": "0.x.x",
  "checkedAt": "2026-08-29T00:00:00Z"
}
```

### Recommended monitoring workflow

1. Run with `monitorMode: true` and a stable `monitorKey`.
2. The first run saves the package baseline and emits `NEW` unless `baselineOnly` is enabled.
3. Run the same input again on a schedule.
4. Unchanged packages emit `UNCHANGED` in normal monitor mode.
5. Set `emitChangesOnly: true` for automation/webhook pipelines that should receive only meaningful changes.

Keep the same package intelligence options across related monitor runs. Turning dependency/release fields on or off changes the normalized state by design.

### Public data sources

#### npm

The Actor reads package metadata from the public npm registry package endpoint and optionally reads point download statistics from npm's public download-count service.

The npm registry response provides the package metadata document, including dist-tags, versions, dependencies, maintainers, repository fields, distribution hashes, and other version metadata.

#### PyPI

The Actor reads the PyPI project JSON endpoint. The project response includes project metadata, all release keys/files, distribution digests, and current project URLs.

**Important:** PyPI documents its JSON `downloads` field as deprecated and always `-1`. This Actor therefore does **not** fabricate PyPI download counts. `downloadStats` is `null` for PyPI records.

### Reliability and cost design

This Actor is deliberately HTTP-only:

- no Playwright/Chromium;
- no residential proxy;
- no Apify Unblocker;
- no CAPTCHA/Cloudflare bypass;
- no third-party API key.

That keeps startup time, memory, platform usage, and maintenance risk low compared with website-specific scraping Actors.

Transient network errors, HTTP `429`, and `5xx` responses use bounded retries. A missing or failed package becomes an `ERROR` record without aborting successful packages in the same run.

### Pay Per Event

The initial monetization configuration defines one primary custom event:

- **Package processed** — `$0.0005` for each successfully fetched and normalized npm/PyPI package.

Failed package fetches are not charged by the Actor's custom event.

At the configured event price, 1,000 successfully processed packages correspond to `$0.50` in Actor event charges, excluding underlying Apify platform usage.

### Output

Structured results are written to the default dataset as:

- `PACKAGE_SNAPSHOT`
- `CHANGE`
- `ERROR`

`RUN_SUMMARY` is written to the default key-value store and includes package counts, registry counts, changes, errors, monitoring mode, billing counts, and charge-limit diagnostics.

### Limitations

- Registry metadata reflects what package publishers/registries expose publicly; it is not an independent identity verification system.
- `vulnerabilityCount`, when present from a source response, is not a complete transitive dependency vulnerability audit.
- npm download spike/drop monitoring compares rolling public point counts. Large changes can reflect real usage shifts, reporting windows, or upstream data behavior.
- PyPI download statistics are intentionally omitted because the official project JSON API does not provide usable download counts.
- This Actor is a **release and supply-chain metadata monitor**, not a replacement for SCA, SBOM, malware analysis, or vulnerability scanners.

# Actor input Schema

## `npmPackages` (type: `array`):

npm package names, including scoped packages such as @types/node.

## `pypiPackages` (type: `array`):

PyPI project names. Names are normalized using PyPI/PEP 503 style comparison for deduplication.

## `maxPackages` (type: `integer`):

Hard cap across npm and PyPI packages after deduplication.

## `includeDependencies` (type: `boolean`):

Include npm dependency groups and PyPI requires\_dist metadata in each snapshot.

## `includeReleaseHistory` (type: `boolean`):

Include a bounded newest-first release history for each package.

## `maxReleaseHistory` (type: `integer`):

Maximum release/version entries retained in each package snapshot.

## `includeDownloadStats` (type: `boolean`):

Fetch public npm download counts for the selected period. PyPI's JSON API does not provide usable download counts, so PyPI records leave this field null.

## `downloadPeriod` (type: `string`):

Public npm downloads API period used for the point download count.

## `monitorMode` (type: `boolean`):

Persist normalized package state and classify changes such as NEW\_VERSION, DEPENDENCY\_CHANGED, MAINTAINER\_CHANGED, LICENSE\_CHANGED, DEPRECATED, YANKED, DOWNLOAD\_SPIKE, and DOWNLOAD\_DROP.

## `emitChangesOnly` (type: `boolean`):

In monitoring mode, suppress package snapshots and UNCHANGED records; emit only meaningful changes and errors.

## `baselineOnly` (type: `boolean`):

Save first-seen package state without emitting the initial NEW event.

## `monitorKey` (type: `string`):

Namespace for persistent monitoring state. Reuse the same value for related scheduled runs.

## `downloadChangeThresholdPercent` (type: `integer`):

Minimum absolute percentage change in npm downloads required to emit DOWNLOAD\_SPIKE or DOWNLOAD\_DROP.

## `concurrency` (type: `integer`):

Maximum package pipelines processed concurrently.

## `requestTimeoutSeconds` (type: `integer`):

Per-request timeout for npm and PyPI public APIs.

## `maxRetries` (type: `integer`):

Retries transient connection, 429, and 5xx responses with bounded backoff.

## Actor input object example

```json
{
  "npmPackages": [
    "react"
  ],
  "pypiPackages": [
    "fastapi"
  ],
  "maxPackages": 100,
  "includeDependencies": true,
  "includeReleaseHistory": true,
  "maxReleaseHistory": 10,
  "includeDownloadStats": true,
  "downloadPeriod": "last-week",
  "monitorMode": false,
  "emitChangesOnly": false,
  "baselineOnly": false,
  "monitorKey": "default",
  "downloadChangeThresholdPercent": 50,
  "concurrency": 10,
  "requestTimeoutSeconds": 20,
  "maxRetries": 2
}
```

# Actor output Schema

## `dataset` (type: `string`):

Normalized npm/PyPI package snapshots, monitoring changes, and errors.

## `runSummary` (type: `string`):

Processed package, registry, change, error, billing, and timing counts.

# API

You can run this Actor programmatically using our API. Below are code examples in JavaScript, Python, and CLI, as well as the OpenAPI specification and MCP server setup.

## JavaScript example

```javascript
import { ApifyClient } from 'apify-client';

// Initialize the ApifyClient with your Apify API token
// Replace the '<YOUR_API_TOKEN>' with your token
const client = new ApifyClient({
    token: '<YOUR_API_TOKEN>',
});

// Prepare Actor input
const input = {
    "npmPackages": [
        "react"
    ],
    "pypiPackages": [
        "fastapi"
    ],
    "maxReleaseHistory": 10
};

// Run the Actor and wait for it to finish
const run = await client.actor("produkdigitalali/npm-pypi-release-supply-chain-monitor").call(input);

// Fetch and print Actor results from the run's dataset (if any)
console.log('Results from dataset');
console.log(`💾 Check your data here: https://console.apify.com/storage/datasets/${run.defaultDatasetId}`);
const { items } = await client.dataset(run.defaultDatasetId).listItems();
items.forEach((item) => {
    console.dir(item);
});

// 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/js/docs

```

## Python example

```python
from apify_client import ApifyClient

# Initialize the ApifyClient with your Apify API token
# Replace '<YOUR_API_TOKEN>' with your token.
client = ApifyClient("<YOUR_API_TOKEN>")

# Prepare the Actor input
run_input = {
    "npmPackages": ["react"],
    "pypiPackages": ["fastapi"],
    "maxReleaseHistory": 10,
}

# Run the Actor and wait for it to finish
run = client.actor("produkdigitalali/npm-pypi-release-supply-chain-monitor").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print(f"💾 Check your data here: https://console.apify.com/storage/datasets/{run.default_dataset_id}")
for item in client.dataset(run.default_dataset_id).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "npmPackages": [
    "react"
  ],
  "pypiPackages": [
    "fastapi"
  ],
  "maxReleaseHistory": 10
}' |
apify call produkdigitalali/npm-pypi-release-supply-chain-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,produkdigitalali/npm-pypi-release-supply-chain-monitor"
        }
    }
}

```

The hosted server signs you in with OAuth on first connect, so no API token belongs in this config. Clients without OAuth support can send an `Authorization: Bearer <APIFY_API_TOKEN>` header instead, using a token from API & Integrations in Apify Console (https://console.apify.com/settings/integrations).

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/actors/4gDYxV9AWxPo7YzYG/builds/YW7wDnbTdKKiilN7b/openapi.json
