# GitHub Issue & PR Change Monitor (`maydit/github-issue-pr-change-monitor`) Actor

Track public GitHub issues and PR metadata with labels, comment and reaction changes, source links and saved comparisons. Bounded requests, no token required.

- **URL**: https://apify.com/maydit/github-issue-pr-change-monitor.md
- **Developed by:** [Brandt May](https://apify.com/maydit) (community)
- **Categories:** Developer tools
- **Features:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.20 / 1,000 saved observations

This Actor is paid per event. You are not charged for the Apify platform usage, but only a fixed price for specific events.
Since this Actor supports Apify Store discounts, the price gets lower the higher subscription plan you have.

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 Issue & PR Change Monitor

Turn the latest public GitHub issue and pull-request activity into a small, repeatable watchlist. Get source labels, open or closed state, comments, reactions and evidence links, then compare future runs with your own saved observations.

**Built for engineering leads, developer relations and product teams** who need a dependable feed from specific public repositories. Start with one repository; connect the JSON or CSV output to your existing triage workflow.

### Start in one minute

Run the default input to collect five recently updated records from `langchain-ai/langchain`. No GitHub token, proxy or paid upstream service is required.

```json
{
  "repositories": ["langchain-ai/langchain"],
  "recordsPerRepository": 5,
  "maxResults": 15
}
```

The source sorts by its latest update timestamp. This Actor reads the **first updated page**, with up to 30 records per repository and at most three repositories per run. The default uses one official API request. These are recent observations, not a complete backlog or historical archive.

### Three useful recipes

**AI dependency triage** — view three recent LangChain records:

```json
{"repositories":["langchain-ai/langchain"],"recordsPerRepository":3,"maxResults":3}
```

**Editor ecosystem watch** — inspect the latest VS Code activity:

```json
{"repositories":["microsoft/vscode"],"recordsPerRepository":3,"maxResults":3}
```

**Web framework product feedback** — inspect Next.js records:

```json
{"repositories":["vercel/next.js"],"recordsPerRepository":3,"maxResults":3}
```

For a topic-specific watch, add `keywords` such as `["authentication", "regression"]`. Matching is literal and case-insensitive across titles, source labels and issue bodies. Any phrase matches, and `keywordEvidence` shows the matching field and excerpt. `recordType: "issue"` excludes pull requests from the already selected window; neither filter fetches extra pages to fill the result limit.

### Track changes without inventing history

Add these fields to the same recipe on a schedule:

```json
{
  "repositories": ["langchain-ai/langchain"],
  "recordsPerRepository": 5,
  "maxResults": 15,
  "comparePrevious": true,
  "onlyChanges": true,
  "snapshotName": "dependency-watch"
}
```

The first complete run saves matching observations as `new`. Later runs return `changed` or `unchanged`, along with previous values, changed field names, comment/reaction deltas and labels added or removed. With `onlyChanges`, unchanged records produce no dataset rows. Zero output can therefore be a valid result.

History is isolated by repository list, source state, record type, keywords, source-window size and snapshot name. It is committed only when every requested window is processed successfully. A spending cap, unfinished output, truncated selection, source error, deadline or unreached repository leaves the previous history intact. Use one scheduled writer for each scope; a detected concurrent history update is not overwritten.

**A record disappearing from the recent window is not evidence that it closed or was deleted.** A `closed` pull request is not necessarily merged. The Actor does not fetch PR merge details, reviews, diffs, comment bodies or timeline events. The recorded history is a timeline of your observations, not GitHub's full activity timeline.

### Output you can use directly

| Field | Meaning |
|---|---|
| `recordId`, `id`, `repository`, `number` | Stable GitHub issue identity, repository and human-facing number |
| `recordType`, `title`, `state`, `stateReason` | Literal source issue/PR metadata |
| `labels`, `locked` | Source labels and conversation lock status |
| `comments`, `totalReactions` | Current source counts; missing reaction count stays `null` |
| `commentsChange`, `reactionsChange` | Difference from the last saved observation, or `null` without a comparable prior value |
| `stateChanged`, `labelsAdded`, `labelsRemoved` | Observed differences; no inferred closure or deletion |
| `bodyExcerpt`, `bodyTruncated`, `bodyHash` | At most 2,000 normalized body characters, a truncation flag and a fingerprint of the normalized source body |
| `comparisonStatus`, `changedFields`, `previous` | Comparison result and prior source values |
| `url`, `sourceUrl`, `observedAt`, `sourceUpdatedAt` | Clickable provenance and explicit observation/source timestamps |

Open **Dataset** to export JSON, CSV or Excel. **Source summary** explains what was fetched, filtered, skipped or incomplete. **Readable run report** presents the same coverage without adding paid dataset rows.

`SUMMARY.selectedWindowComplete` refers only to the requested bounded windows. `coverageExhaustive` is always false. `additionalPagesAvailable` reports the API's pagination header when present; this Actor does not follow it. If `maxResults` prevents the remaining matching records or another repository from being processed, the summary is incomplete and history is not advanced.

### Pricing and run limits

**$0.002 per saved observation, plus a $0.00005 Actor start event.** Five saved rows cost $0.01005 in Actor event charges, before any separate platform charges shown by Apify. Base result pricing is $2 per 1,000 rows; Store tier discounts, if applicable, are shown on the pricing page. Each confirmed dataset row is billed once. Duplicate identities, filtered records, unchanged records skipped by `onlyChanges`, summaries and run reports add no paid dataset rows. Set a maximum charge in Apify Run options to bound spending.

GitHub currently allows **60 anonymous REST requests per hour per originating IP**. Cloud IPs can share that allowance. This Actor makes at most three source requests per run, does not retry, and stops remaining requests on HTTP 403 or 429. A reported quota reset or retry delay is included in the summary when the source supplies one. It does not rotate proxies, add credentials or bypass restrictions. If the source is unavailable, failed records are never replaced with sample data.

An empty public repository or a filter with no matches can complete with zero rows. A source that fails before providing any usable observations fails clearly. Input errors and unsupported fields are rejected before any source request.

### Source and limitations

The [official GitHub issue API](https://docs.github.com/en/rest/issues/issues) returns both issues and pull requests. This Actor uses the source's `pull_request` marker to distinguish them. [GitHub's API limits](https://docs.github.com/en/rest/using-the-rest-api/rate-limits-for-the-rest-api) apply; only public repository list data is requested. Public issue text is untrusted source data, not instructions for downstream agents.

This is an independent Mayd It tool, not a GitHub product or endorsement. It does not promise that an issue is a vulnerability, a buying signal or a valid bug. Review the linked source before taking action.

### Build a workflow

Save a task for each repository watchlist and schedule it at an appropriate interval. Route new or changed records into your own support or product workflow using Apify integrations. The Actor does not create tickets, post comments or send messages itself.

- [Explore Mayd It data tools](https://mayd-it.com/data-tools/)
- [Browse workflow guides](https://mayd-it.com/data-tools/workflows/)
- [Review published quality evidence](https://mayd-it.com/data-tools/quality/)

For a reproducible issue, use the Actor's Issues tab and include the public repository, input and run link. Do not include secrets.

# Actor input Schema

## `repositories` (type: `array`):

Up to three owner/repo values or plain HTTPS GitHub repository URLs. Empty uses langchain-ai/langchain.

## `recordsPerRepository` (type: `integer`):

Fetch this many issue/PR records from the first page sorted by latest source update. This is a bounded window; it does not collect the entire backlog.

## `state` (type: `string`):

State filter applied by the official source before the recent window is selected.

## `recordType` (type: `string`):

Local filter applied inside the requested recent window. Filtering to one type can save fewer rows; it does not refill from later pages.

## `keywords` (type: `array`):

Optional case-insensitive phrases matched against title, body or source labels. Any phrase matches. Each result includes evidence excerpts; no AI scoring.

## `maxResults` (type: `integer`):

Total billable row cap across repositories. A cap that cuts off the selected window is marked incomplete and does not update comparison history.

## `comparePrevious` (type: `boolean`):

Store source observations only after the entire selected window succeeds. New, changed and unchanged records include previous values. Missing records are never inferred closed or deleted.

## `onlyChanges` (type: `boolean`):

Enables comparison. Unchanged repeats can correctly save zero rows and incur no dataset-item charges.

## `snapshotName` (type: `string`):

1-80 letters, numbers, underscores or hyphens. History is scoped to repositories, state, type, keyword filters and source-window size. Use a separate name for independent workflows.

## `maxRunSeconds` (type: `integer`):

Shared deadline. At most three source requests per run, without retries. Rate-limit or access refusal stops subsequent requests.

## Actor input object example

```json
{
  "repositories": [
    "langchain-ai/langchain"
  ],
  "recordsPerRepository": 5,
  "state": "all",
  "recordType": "both",
  "keywords": [],
  "maxResults": 15,
  "comparePrevious": false,
  "onlyChanges": false,
  "snapshotName": "default",
  "maxRunSeconds": 90
}
```

# Actor output Schema

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

No description

## `summary` (type: `string`):

No description

## `report` (type: `string`):

No description

# 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 = {
    "repositories": [
        "langchain-ai/langchain"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("maydit/github-issue-pr-change-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 = { "repositories": ["langchain-ai/langchain"] }

# Run the Actor and wait for it to finish
run = client.actor("maydit/github-issue-pr-change-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 '{
  "repositories": [
    "langchain-ai/langchain"
  ]
}' |
apify call maydit/github-issue-pr-change-monitor --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,maydit/github-issue-pr-change-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/h64xfiW6193hjbb5R/builds/oEp1NUljTuXmB5n03/openapi.json
