# GitHub Releases & Package Release Notes (`miacx/github-releases-package-release-notes`) Actor

Get releases from GitHub, npm, PyPI, crates.io, feeds and changelog pages in one format. Batch targets and filter versions. Pay per returned release.

- **URL**: https://apify.com/miacx/github-releases-package-release-notes.md
- **Developed by:** [mia.cx](https://apify.com/miacx) (community)
- **Categories:** Developer tools
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.80 / 1,000 releases

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?

An Actor is a serverless cloud program that runs on the Apify platform. It has two run modes.
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.

Apify vocabulary and the platform model are defined once, in the agent quickstart at https://apify.com/agents.md.

## 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.

Do not guess an integration path. Every one of them is in the agent quickstart at https://apify.com/agents.md: the Apify MCP server, Agent Skills with the Apify CLI, the JavaScript and Python clients, the REST API, and the account-free path for an agent with no human to sign in. It also carries the rule on stating cost before the first paid run.

For examples already wired to this Actor's own input schema, see the [API](#api) section below.

Each client library has reference documentation the quickstart does not restate: [JavaScript/TypeScript](https://docs.apify.com/api/client/js/docs.md) (`npm install apify-client`) and [Python](https://docs.apify.com/api/client/python/docs.md) (`pip install apify-client`).

# README

## GitHub Releases & Package Release Notes

Give an agent releases from several projects in one format, with optional date or version filters.
Read GitHub, npm, PyPI, crates.io, RSS/Atom feeds and changelog pages.
Registry releases and GitHub tags contain version metadata without note bodies.
Each delivered release costs $0.0018, plus $0.00005 per run start at default memory.

### Try it

```json
{"targets":["npm:ky"],"limit":1}
```

Empty input `{}` requests up to three releases each for `npm:ky`, `pypi:requests` and `crates:serde`.
No upstream key is required. An optional caller-supplied `githubToken` enables authenticated GitHub requests.

### Use from an agent

Add `https://mcp.apify.com?tools=miacx/github-releases-package-release-notes` to your MCP client and sign in to Apify.
Call the dedicated Actor tool, then use `get-dataset-items` to read the completed run's dataset.
Or set `APIFY_TOKEN` to your Apify API token and call the API:

```sh
curl --fail-with-body 'https://api.apify.com/v2/actors/miacx~github-releases-package-release-notes/run-sync-get-dataset-items' \
  -H "Authorization: Bearer $APIFY_TOKEN" -H 'Content-Type: application/json' \
  -d '{"targets":["npm:ky"],"limit":1}'
```

### What you get

The dataset contains one row per delivered release, plus unbilled failed-target and zero-release status rows.
Read `status` first. An `ok` row with `releases: 0` is a target summary, not a delivered release.
One failed target does not stop the rest of the batch.

This row comes from replaying the recorded npm fixture through the Actor adapter with a fixed test clock:

```json
{
  "target": "npm:ky",
  "status": "ok",
  "version": "2.2.0",
  "date": "2026-10-09T06:32:47.556Z",
  "title": "ky 2.2.0",
  "body": null,
  "url": "https://www.npmjs.com/package/ky/v/2.2.0",
  "breaking": false,
  "source": "https://registry.npmjs.org/ky",
  "fetchedAt": "1970-01-01T00:00:00.000Z"
}
```

`version` is null when the source supplies no detectable version. Leading `v` is removed.
`date` is a UTC timestamp or `YYYY-MM-DD` for sources that supply only a day; undated releases have null dates.
`body` is source Markdown or converted feed/changelog text. It is null for registries, tags and sources without notes.
`url` is null when unavailable. Changelog releases link to the page, without heading anchors.

`breaking` is a heuristic based on note markers or versions starting a new caret compatibility line.
It flags `X.0.0`, `0.Y.0`, `0.0.Z` and their prereleases, including a project's first release.
It can miss unmarked breaking changes. It does not establish upgrade compatibility.

The key-value store's `OUTPUT` record reports each target, including errors and targets with no releases.
Successful summaries include delivered `releases`, budget `withheld`, `truncated` and `sinceSkipped` counts.
`chargeLimitReached` reports whether any releases were withheld.
`truncated` means more matches may exist; `sinceSkipped` counts entries whose date or version cannot be compared.

### Input

| Field | Default | Accepted input |
| --- | --- | --- |
| `targets` | `["npm:ky","pypi:requests","crates:serde"]` | 1–500 strings or objects from the target table below. An empty array is invalid. |
| `sinceDate` | `""` | Keep releases strictly after a date or timestamp. Empty means no filter. |
| `limit` | `3` | 1–100 releases per target after filtering. |
| `githubToken` | Omitted | Optional caller-supplied token sent only to api.github.com. Empty means unauthenticated access. |

| Target kind | Value | Returned source data |
| --- | --- | --- |
| `github` | `owner/repo` | Releases, excluding drafts; first page only, up to 100 entries. |
| `github-tags` | `owner/repo` | Tags ordered by SemVer, without dates or notes. |
| `npm` | Package name, including scopes | Registry versions and publication dates. |
| `pypi` | Project name | Versions and publication dates, excluding fully yanked releases. |
| `crates` | Crate name | Versions and publication dates, excluding yanked releases. |
| `feed` | Public HTTPS URL | RSS 2.0, RSS 1.0 or Atom entries. |
| `changelog` | Public HTTPS URL | Version headings in HTML, Markdown or plain text. |

Strings use `kind:value`, such as `github:sindresorhus/ky`.
Objects contain exactly one kind key and optional `sinceDate`, `sinceVersion` or `selector`:

```json
{
  "targets": [
    {"pypi":"django","sinceVersion":"5.0"},
    {"changelog":"https://www.sqlite.org/changes.html","sinceDate":"2026-01-01"}
  ],
  "limit": 5
}
```

Per-target `sinceDate` or `sinceVersion` overrides the batch date. Supplying both fails that target.
A bare date means after that whole UTC day. Date-times require `Z` or a timezone offset.
A day-only release that straddles a timestamp boundary is excluded and counted in `sinceSkipped`.
Undated entries also count in `sinceSkipped`; use `sinceVersion` for GitHub tags.

`sinceVersion` accepts up to 100 characters and compares strictly greater versions.
PyPI uses PEP 440; other kinds use strict SemVer 2.0. Unorderable release versions count in `sinceSkipped`.
`selector` accepts up to 200 characters and scopes HTML changelogs only.
Caller URLs allow up to 2,048 characters and must use public HTTPS on port 443 without embedded credentials.
See the [input schema](.actor/input_schema.json) for the Actor contract.

### Pricing

One Release costs $0.0018 and counts one delivered release row, including cached output.
Failed targets, zero-release summaries and withheld releases incur no Release events.

Identical normalized targets with identical options merge within one run.
Different filters or selectors are separate targets and can return and charge the same release again.

One thousand Release events cost $1.80, plus $0.00005 per run start at default memory.
The one-release example costs $0.00185 including startup. The default nine-release example costs up to $0.01625.
Default memory is 128 MB. Apify counts one start event per GB of memory, with a minimum of one event.
The $0.00005 run start at default memory applies even with no billable releases.

The Actor uses remaining charge capacity to select rows before delivery.
Read `OUTPUT` for withheld counts; raise the budget to receive more matches.

### Limits and data freshness

- A run accepts 500 targets, fetches eight concurrently and gives each target a 20-second upstream budget.
- GitHub reads at most 100 entries from one page. Feeds expose a window and always report `truncated`.
- Response limits are 5 MiB for caller URLs, 10 MiB for GitHub and 24 MiB for registries.
- Changelog extraction needs version headings; dates must appear as `YYYY-MM-DD` in the heading. Atom XHTML content is not read.
- Feed and changelog requests honor robots.txt, block private addresses and recheck up to three redirects. No browser or runtime LLM runs.

Parsed public snapshots are fresh for five minutes, then revalidated when requested.
`fetchedAt` marks the last upstream fetch or HTTP 304 confirmation; cache hits retain that time.
The named store `release-watch-cache` persists across runs without automatic pruning.
Responses fetched with `githubToken` are never cached.

The synchronous API waits up to 300 seconds. For larger batches, use [asynchronous runs](https://docs.apify.com/api/v2/actor-runs-post).

### If a row fails

| Status | Next step |
| --- | --- |
| `invalid_target`, `invalid_since` | Correct the target kind, object options or date/version format. |
| `not_found`, `forbidden` | Check the project or URL and public access. |
| `rate_limited` | Honor `error.retryAfter` seconds when present; retry later. |
| `unsafe_url`, `robots_disallowed`, `robots_unavailable` | Use an accessible public HTTPS source that permits retrieval. GitHub Atom feeds may require the `github` kind instead. |
| `selector_not_found`, `no_releases_detected`, `unsupported_content` | Check the HTML selector, version headings and content format. |
| `response_too_large`, `parse_error` | Read `error.message`; the source exceeds limits or has an unsupported response shape. |
| `timeout`, `network_error`, `upstream_error` | Retry later or split the batch. |
| `internal_error` | Report the target and error message. |

Explicit empty targets, a non-object input or an invalid batch limit fail the run before target processing.

# Actor input Schema

## `targets` (type: `array`):

1–500 strings using github:owner/repo, github-tags:owner/repo, npm:name, pypi:name, crates:name, feed:https://URL or changelog:https://URL. Objects add sinceDate, sinceVersion or selector, e.g. {"pypi":"django","sinceVersion":"5.0"}. Defaults to npm:ky, pypi:requests and crates:serde; \[] is invalid. Exact normalized target/options duplicates merge per run. Different filters can return and charge the same release.

## `sinceDate` (type: `string`):

ISO date or date-time; empty or omitted means no filter. Keeps releases strictly after the instant. YYYY-MM-DD means after that whole UTC day; date-times need Z or a timezone offset. Per-target sinceDate or sinceVersion overrides this value. Undated or ambiguous releases are excluded and counted in sinceSkipped.

## `limit` (type: `integer`):

Integer from 1 to 100, default 3. Maximum releases per target after filtering; usually newest publication first, with GitHub tags ordered by SemVer. Each delivered release incurs one Release event. GitHub reads only its first page of up to 100 entries.

## `githubToken` (type: `string`):

Optional caller-supplied GitHub token, sent only to api.github.com. Omitted or empty uses unauthenticated public access. Use a fine-grained token with public repository read access. Authenticated GitHub requests use the token's rate limit; responses are never cached.

## Actor input object example

```json
{
  "targets": [
    "npm:ky",
    "pypi:requests",
    "crates:serde"
  ],
  "sinceDate": "",
  "limit": 3
}
```

# Actor output Schema

## `releases` (type: `string`):

One item per delivered (billed) release with status ok, plus unbilled error and zero-release target statuses.

## `status` (type: `string`):

OUTPUT record: every target's result, including targets with zero releases and failures.

# 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 = {
    "targets": [
        "npm:ky",
        "pypi:requests",
        "crates:serde"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("miacx/github-releases-package-release-notes").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 = { "targets": [
        "npm:ky",
        "pypi:requests",
        "crates:serde",
    ] }

# Run the Actor and wait for it to finish
run = client.actor("miacx/github-releases-package-release-notes").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 '{
  "targets": [
    "npm:ky",
    "pypi:requests",
    "crates:serde"
  ]
}' |
apify call miacx/github-releases-package-release-notes --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,miacx/github-releases-package-release-notes"
        }
    }
}
```

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/JkK7i1pYPc7GytfF5/builds/X9w2Lcf8RD8Dbt7zO/openapi.json
