# GitHub Public Issue Monitor (`snappytools/github-issue-monitor`) Actor

Track issues across public GitHub repositories and receive clean, consistently structured records you can filter, sort and feed into spreadsheets, dashboards or alerting workflows.

- **URL**: https://apify.com/snappytools/github-issue-monitor.md
- **Developed by:** [Snappy](https://apify.com/snappytools) (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

$1.90 / 1,000 results

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 Issue Monitor – public GitHub issues export and API

Give it a list of public GitHub repositories and get back one row per issue. Each row has the repository, issue number, title, state, labels, comment count, author and timestamps. You can filter by state, labels and last-updated date, and choose how results are sorted.

Pull requests can be included too. They are flagged with `isPullRequest`, so you can keep them or filter them out later. Schedule it to run daily and use the **Updated since** filter to get only what changed.

### Why this one

- **No login or token.** It reads public issue data only, so there is nothing to set up.
- **Clean, consistent records.** Every row uses the same field names, so spreadsheets and dashboards don't break.
- **Filters that match how you work.** Pick open, closed or all issues, require labels like `bug,good first issue`, and set a date with **Updated since**.
- **Many repositories in one run.** Add up to 20 repositories as `owner/repo` or a full GitHub link.
- **Bounded cost.** **Max items per repository** (1 to 500) caps how much each repository can return.
- **Simple pricing.** $1.90 per 1,000 results, with no start fee. Runs that return nothing cost nothing.

### Quick start

```json
{
  "repositories": ["nodejs/node", "apify/crawlee"],
  "state": "all",
  "sort": "updated",
  "direction": "desc",
  "maxItemsPerRepo": 5,
  "includePullRequests": true,
  "includeBodyExcerpt": false
}
```

This returns the 5 most recently updated issues and pull requests from each repository. In a test run on 26 Oct 2026 it returned 10 records.

### What you can use it for

| Who | What for |
|---|---|
| Developer relations and open-source teams | Watch new and updated issues across the repositories you maintain |
| Engineering managers | Check the bug backlog of a key dependency before you upgrade |
| Product researchers | Gauge demand by label, comment count and reactions |
| Contributors and consultants | Find `good first issue` or `help wanted` work |
| Support teams | Send a daily digest of recently updated issues using **Updated since** |

### How to use it

1. Click **Try for free**.
2. In **Repositories**, add the public repositories to watch, for example `nodejs/node` or `https://github.com/apify/crawlee`. The limit is 20.
3. Set **Issue state** to `open`, `closed` or `all`.
4. Optionally add a **Labels filter**, such as `bug,good first issue`. An issue must carry all the labels listed.
5. Optionally set **Updated since** to a date like `2026-10-01`.
6. Choose **Sort by** (`updated`, `created` or `comments`) and **Sort direction** (`desc` or `asc`).
7. Set **Max items per repository**, and turn on **Include pull requests** or **Include body excerpt** if you want them.
8. Click **Start**.

To track changes, schedule the Actor and set **Updated since** to the date of your last run.

### What data you get

Each row is one issue or pull request. If you turn on **Include body excerpt**, a `bodyExcerpt` field with the first 500 characters of the description is added.

| Field | What it is | Example |
|---|---|---|
| `id` | Repository and issue number | `nodejs/node#66872` |
| `url` | Link to the issue or pull request on github.com | `https://github.com/nodejs/node/pull/66872` |
| `apiUrl` | GitHub API link for the item | `https://api.github.com/repos/nodejs/node/issues/66872` |
| `githubNodeId` | GitHub's internal node ID | `PR_kwDOAZ7xs88AAAABJhS0Iw` |
| `repository` | Repository the item belongs to | `nodejs/node` |
| `number` | Issue or pull request number | `66872` |
| `title` | Title | `url: use indexed appends in search params getAll` |
| `state` | Open or closed | `open` |
| `stateReason` | Reason an issue was closed, if any | `null` |
| `isPullRequest` | True if the item is a pull request | `true` |
| `isLocked` | True if the conversation is locked | `false` |
| `labels` | Label names | `["whatwg-url","author ready","needs-ci"]` |
| `assignees` | Assigned users | `[]` |
| `milestone` | Milestone, if any | `null` |
| `comments` | Number of comments | `4` |
| `reactionsTotal` | Total reactions | `0` |
| `author` | Username of the author | `rozzilla` |
| `authorAssociation` | Author's relationship to the repository | `CONTRIBUTOR` |
| `createdAt` | When it was created | `2026-10-20T09:35:05Z` |
| `updatedAt` | When it was last updated | `2026-10-26T16:14:55Z` |
| `closedAt` | When it was closed, if it was | `null` |
| `ageDays` | Days since it was created | `6` |
| `scrapedAt` | When the record was collected | `2026-10-26T16:15:11.817Z` |

### Pricing

| Event | Price |
|---|---|
| Result (one record saved to the dataset) | $0.0019 |

There is no start fee. Runs with no results cost nothing.

| Run | Cost |
|---|---|
| 100 results | $0.19 |
| 1,000 results | $1.90 |
| 10,000 results | $19.00 |

### Good to know

- **Data source.** It uses the public GitHub REST API. Only repositories that are public can be read, and private repositories are never requested.
- **Limits.** Up to 20 repositories per run and up to 500 records per repository.
- **Rate limits.** No token is used, so GitHub's limit for unauthenticated access applies (roughly 60 requests per hour per IP address). If it is reached, the run stops and keeps what it has already saved.
- **Missing repositories.** Repositories that don't exist or aren't public are skipped with a warning.
- **Empty results.** Narrow filters, such as a rare label or a recent date, can return zero records.
- **Pull requests.** They are left out by default. Turn on **Include pull requests** to keep them.
- **Freshness.** Records show the state at collection time. Check `scrapedAt`, because issues can change afterwards.
- **Run summary.** A `RUN_SUMMARY` record in the key-value store has per-repository counts and any failures.
- **Not affiliated.** This tool isn't affiliated with or endorsed by GitHub.

### FAQ

**Do I need a GitHub token?** No. It only reads public data.

**Does the labels filter match any label or all of them?** All of them. An issue must carry every label you list.

**Why did I get pull requests in my results?** GitHub lists pull requests alongside issues. Turn off **Include pull requests** to leave them out, or filter on `isPullRequest`.

**Can I paste full GitHub links?** Yes. Use `owner/repo` or `https://github.com/owner/repo`.

### Getting the data out

Download the results as Excel, CSV or JSON from the Output tab. Send them to Google Sheets, Slack, Zapier, Make or webhooks from the **Integrations** tab. Every run is also available through the Apify API, and you can schedule runs from **Schedules**.

### Questions or problems

Open an issue on the **Issues** tab and include the run link. I reply within one business day.

### Related tools

- [GitHub Public Release Monitor](https://apify.com/snappytools/github-release-monitor): track new releases from public repositories
- [NPM Package Version Monitor](https://apify.com/snappytools/npm-package-version-monitor): watch npm packages for new versions
- [PyPI Package Release Monitor](https://apify.com/snappytools/pypi-release-monitor): watch PyPI packages for new releases

# Actor input Schema

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

Public GitHub repositories to monitor, as owner/repo or https://github.com/owner/repo. Maximum 20 repositories per run.

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

Which issues to return: only open, only closed, or all issues regardless of state.

## `labels` (type: `string`):

Optional comma-separated label names. Only issues carrying ALL listed labels are returned, e.g. bug,good first issue.

## `since` (type: `string`):

Optional ISO 8601 date or timestamp. Only issues updated at or after this moment are returned, e.g. 2024-01-01.

## `sort` (type: `string`):

Field GitHub uses to order results before the per-repository limit is applied.

## `direction` (type: `string`):

Sort direction: descending returns newest or most-commented first, ascending returns oldest first.

## `maxItemsPerRepo` (type: `integer`):

Maximum number of records saved for each repository (1-500). Keeps runs and per-result costs bounded.

## `includePullRequests` (type: `boolean`):

GitHub's issues endpoint also lists pull requests. Enable to keep them (flagged with isPullRequest=true).

## `includeBodyExcerpt` (type: `boolean`):

Add the first 500 characters of the public issue description as bodyExcerpt for keyword triage.

## Actor input object example

```json
{
  "repositories": [
    "nodejs/node",
    "apify/crawlee"
  ],
  "state": "all",
  "sort": "updated",
  "direction": "desc",
  "maxItemsPerRepo": 10,
  "includePullRequests": true,
  "includeBodyExcerpt": false
}
```

# Actor output Schema

## `results` (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": [
        "nodejs/node",
        "apify/crawlee"
    ],
    "state": "all",
    "maxItemsPerRepo": 10,
    "includePullRequests": true
};

// Run the Actor and wait for it to finish
const run = await client.actor("snappytools/github-issue-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": [
        "nodejs/node",
        "apify/crawlee",
    ],
    "state": "all",
    "maxItemsPerRepo": 10,
    "includePullRequests": True,
}

# Run the Actor and wait for it to finish
run = client.actor("snappytools/github-issue-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": [
    "nodejs/node",
    "apify/crawlee"
  ],
  "state": "all",
  "maxItemsPerRepo": 10,
  "includePullRequests": true
}' |
apify call snappytools/github-issue-monitor --silent --output-dataset

```

## MCP server setup

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