# GitHub Repo Health Checker – Awesome-List Link Audit (`mikestart/github-repo-health`) Actor

Is a GitHub repo still alive? Stars, forks, last commit, issues, archived flag, license and an active/stale/dead score for repo lists or awesome-lists. Official GitHub API. By Mike Start Games. This is not personalized advice. Material created also with the use of AI tools.

- **URL**: https://apify.com/mikestart/github-repo-health.md
- **Developed by:** [Mike](https://apify.com/mikestart) (community)
- **Categories:** Developer tools, Open source, Automation
- **Security:** Limited permissions
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $7.50 / 1,000 repository checkeds

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 Repo Health Checker – is this repository still alive?

Check any list of GitHub repositories – or a whole **awesome-list** – in one run and get, for every repo:
**stars, forks, last commit date, open issues, archived flag, license** and a simple health score:
**active / stale / dead**.

- **Two inputs, one table**: paste repository URLs (`owner/repo`, `https://github.com/owner/repo`, `git@github.com:…`)
  and/or the URL of an awesome-list (a GitHub README, or any raw Markdown / JSON / YAML file).
- **Link extraction done right**: GitHub links are de-duplicated; topics, orgs, gists, docs, GitHub Pages, issues and
  other non-repository links are dropped.
- **Health score you control**: active = last commit ≤ 90 days, stale = ≤ 365 days, dead = older or archived (both thresholds configurable).
- **Renamed / transferred repos detected** (`status: moved`, `movedFrom`), and **broken links** reported as free rows
  (`not-found`, `blocked`), so you can clean up a list.
- **Official GitHub REST API only** (`api.github.com`). No scraping of github.com pages, no browser, no proxies.
- **Rate-limit aware**: reads `X-RateLimit-Remaining` / `X-RateLimit-Reset`, never hammers the API, waits (if you allow it)
  or stops cleanly with a clear message. Optional token for 5,000 requests/hour.
- **Pay only for what works**: you are charged per repository successfully checked; unavailable or skipped repos are free.

Created with the help of AI by **Mike Start Games**.

> **Disclaimer:** This is not personalized advice. Material created also with the use of AI tools.

### Use cases

- **Awesome-list maintainers** – find dead, archived, moved and deleted projects before your readers do.
- **Developers choosing a dependency** – compare candidates by activity, license and stars in one table.
- **Investors, analysts and dev-rel** – snapshot of an ecosystem (e.g. all AI-agent frameworks) with activity levels.
- **Security / OSPO teams** – spot unmaintained or unlicensed repositories in your dependency list.
- **Content creators** – keep "best tools" articles up to date.

#### Example: audit the "Awesome AI Agents" list

[slavakurilyak/awesome-ai-agents](https://github.com/slavakurilyak/awesome-ai-agents) (MIT License, © its authors) links to
\~300 AI-agent projects. With a token:

```json
{
  "awesomeListUrls": ["https://github.com/slavakurilyak/awesome-ai-agents"],
  "githubToken": "github_pat_…",
  "maxRepos": 500
}
```

In our test the README contained **302 unique repository links** (the list's own repo is excluded by default).
The dataset view **"Dead or unavailable"** gives you the clean-up list directly. If you republish the results, cite the
list as the source, as its MIT license requires.

### Input

| Field | Type | Default | Description |
|---|---|---|---|
| `repos` | array | – | Repositories: `owner/repo`, GitHub URL (any sub-page) or SSH URL. |
| `awesomeListUrls` | array | – | Lists to read: GitHub repo URL (README), GitHub file URL (`/blob/…`) or raw Markdown/JSON/YAML/HTML URL. |
| `includeListRepo` | boolean | `false` | Also check the list's own repository. |
| `maxRepos` | integer | 25 without token, 1,000 with token | Max unique repos per run (max 5,000). |
| `githubToken` | string (secret) | – | Optional GitHub token. A fine-grained token with **no permissions** is enough. Encrypted by Apify, never logged or output. |
| `checkLastCommit` | boolean | `true` | 2 requests/repo for the real last commit on the default branch; off = 1 request/repo using `pushed_at`. |
| `maxRateLimitWaitSecs` | integer | `0` | Wait for a rate-limit reset if it comes within this many seconds; otherwise stop cleanly. |
| `maxConcurrency` | integer | 2 / 4 | Repos checked in parallel (without / with token). |
| `activeDays` | integer | `90` | Active threshold in days. |
| `staleDays` | integer | `365` | Stale threshold in days (must be > `activeDays`). |
| `includeErrorRows` | boolean | `true` | Output free rows for repos that could not be checked. |

At least one of `repos` or `awesomeListUrls` is required.

#### Without a token

GitHub allows **60 requests per hour per IP address** without a token, and on Apify that IP can be shared with other
users. Each repo costs 2 requests (1 with `checkLastCommit: false`), so without a token keep runs small (default 25 repos).
When the quota runs out the Actor **stops cleanly**: remaining repos get a free `rate-limited` row and the SUMMARY explains
when the quota resets. For anything bigger, create a token at <https://github.com/settings/personal-access-tokens>
(no permissions needed) and paste it in `githubToken`.

### Output

One row per repository (dataset), plus a `SUMMARY` record in the key-value store.

```json
{
  "url": "https://github.com/langchain-ai/langchain",
  "owner": "langchain-ai",
  "name": "langchain",
  "fullName": "langchain-ai/langchain",
  "status": "moved",
  "statusMessage": "Repository was renamed or transferred to langchain-ai/langchain.",
  "description": "The agent engineering platform.",
  "stars": 148769,
  "forks": 25000,
  "openIssues": 706,
  "lastCommitDate": "2026-10-31T15:17:54Z",
  "lastCommitSource": "default-branch-commit",
  "pushedAt": "2026-10-31T15:17:58Z",
  "archived": false,
  "license": "MIT",
  "defaultBranch": "master",
  "healthScore": "active",
  "healthScoreIt": "attivo",
  "daysSinceLastCommit": 0,
  "movedFrom": "hwchase17/langchain",
  "sourceList": null,
  "checkedAt": "2026-10-31T16:28:22.253Z"
}
```

| Field | Meaning |
|---|---|
| `status` | `ok`, `moved` (renamed/transferred, followed automatically), `not-found` (deleted, private or wrong URL), `blocked` (HTTP 451), `error`, `rate-limited` (not checked). |
| `healthScore` | `active`, `stale`, `dead` (archived or too old), `unknown` (no date available). `healthScoreIt` is the Italian label (`attivo`, `fermo`, `morto`). |
| `lastCommitDate` | Committer date of the latest commit on the default branch; `lastCommitSource` tells if `pushed_at` was used instead. |
| `openIssues` | GitHub's `open_issues_count`, which includes open pull requests. |
| `license` | SPDX id (`MIT`, `Apache-2.0`…), `NOASSERTION` if GitHub cannot identify it, `null` if there is none. |
| `sourceList` | The list URL the repo was found in (null for repos given directly). |

Other fields: `description`, `stars`, `forks`, `pushedAt`, `createdAt`, `isFork`, `defaultBranch`, `language`, `topics`, `homepage`.

### Pricing (pay per event)

| Event | Price |
|---|---|
| Actor start | $0.005 per run |
| Repository checked | $0.0075 per repository successfully checked (`ok` or `moved`) |

Rows for unavailable, blocked and rate-limited repositories are **free**. Example: auditing a 300-repo awesome-list costs
about **$2.26**. You can set a maximum cost per run in Apify; the Actor stops when it is reached.

### Data and privacy

- Data comes only from the official GitHub REST API and from the list files you provide.
- The Actor stores repository metadata only. The only personal element is the **public login of the repository owner**,
  which is part of the repository URL. No e-mails, names of committers, avatars or follower data are collected.
- Use of the GitHub API is subject to the [GitHub Terms of Service](https://docs.github.com/en/site-policy/github-terms/github-terms-of-service)
  and its API rate limits, which this Actor respects. You are responsible for how you use the output.

### FAQ

**Why is a repo "dead" although it had a commit last week?** It is archived: archived repositories are always dead.
**Why did my run stop early?** The GitHub rate limit was reached; see `SUMMARY.rateLimit.stoppedReason`, or add a token.
**Can it check private repositories?** No. Only public repositories are reported, even if your token could see more.

***

Created with the help of AI · © Mike Start Games · Not affiliated with GitHub, Inc.

# Actor input Schema

## `repos` (type: `array`):

GitHub repositories to check, one per line. Accepted: <code>owner/repo</code>, <code>https://github.com/owner/repo</code> (any sub-page such as /tree/main is fine) or <code>git@github.com:owner/repo.git</code>. Entries that are not repositories (topics, orgs, other hosts) are ignored and listed in the run SUMMARY.

## `awesomeListUrls` (type: `array`):

Lists to extract GitHub repository links from. Accepted: a GitHub repository URL (its README is read, 1 API request), a GitHub file URL (<code>/blob/…</code>, read from raw.githubusercontent.com without API quota) or any raw Markdown / JSON / YAML / HTML URL. Links are de-duplicated; non-repository links (topics, gists, docs, GitHub Pages, issues) are dropped.

## `includeListRepo` (type: `boolean`):

When a list is itself a GitHub repo, also check that repo (off by default: lists often link to themselves in badges).

## `maxRepos` (type: `integer`):

Maximum number of unique repositories checked in this run (after de-duplication, in input order). If empty: 25 without a token (GitHub allows only 60 requests/hour without a token) or 1,000 with a token.

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

Optional personal access token, used only to call api.github.com with a higher rate limit (5,000 requests/hour instead of 60). A fine-grained token with <b>no permissions</b> (public repositories, read-only) is enough. It is stored encrypted by Apify and never logged or saved to the output.

## `checkLastCommit` (type: `boolean`):

On: 2 API requests per repo, the date of the latest commit on the default branch is used. Off: 1 request per repo, GitHub's <code>pushed_at</code> (last push to any branch) is used instead. Turn off to check twice as many repos without a token.

## `maxRateLimitWaitSecs` (type: `integer`):

If the GitHub rate limit is reached and it resets within this many seconds, the run waits and continues; otherwise it stops cleanly and the remaining repos get a free <code>rate-limited</code> row. Waiting uses compute time, so the default is 0 (stop).

## `maxConcurrency` (type: `integer`):

Repositories checked in parallel. Default 2 without a token, 4 with a token (GitHub discourages heavy parallel use).

## `activeDays` (type: `integer`):

A repository is <b>active</b> if its last commit is at most this many days old and it is not archived.

## `staleDays` (type: `integer`):

A repository is <b>stale</b> if its last commit is older than the active threshold but at most this many days old. Older, or archived, means <b>dead</b>. Must be greater than the active threshold.

## `includeErrorRows` (type: `boolean`):

Also output a row (free, not charged) for repos that are not found, private, blocked or skipped because of the rate limit, with <code>status</code> and <code>statusMessage</code>. Useful to find broken links in a list.

## Actor input object example

```json
{
  "repos": [
    "apify/crawlee",
    "https://github.com/microsoft/autogen",
    "https://github.com/hwchase17/langchain"
  ],
  "awesomeListUrls": [],
  "includeListRepo": false,
  "checkLastCommit": true,
  "maxRateLimitWaitSecs": 0,
  "activeDays": 90,
  "staleDays": 365,
  "includeErrorRows": true
}
```

# Actor output Schema

## `results` (type: `string`):

One row per repository: stars, forks, last commit, open issues, archived, license and active/stale/dead score (plus free rows for unavailable repos).

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

Totals per health score and status, lists read, ignored inputs and GitHub rate-limit usage.

# 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 = {
    "repos": [
        "apify/crawlee",
        "https://github.com/microsoft/autogen",
        "https://github.com/hwchase17/langchain"
    ],
    "awesomeListUrls": []
};

// Run the Actor and wait for it to finish
const run = await client.actor("mikestart/github-repo-health").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 = {
    "repos": [
        "apify/crawlee",
        "https://github.com/microsoft/autogen",
        "https://github.com/hwchase17/langchain",
    ],
    "awesomeListUrls": [],
}

# Run the Actor and wait for it to finish
run = client.actor("mikestart/github-repo-health").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 '{
  "repos": [
    "apify/crawlee",
    "https://github.com/microsoft/autogen",
    "https://github.com/hwchase17/langchain"
  ],
  "awesomeListUrls": []
}' |
apify call mikestart/github-repo-health --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "type": "http",
            "url": "https://mcp.apify.com/?tools=fetch-actor-details,mikestart/github-repo-health"
        }
    }
}
```

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/D9n7T1Pl9zwaBpAkX/builds/ewluhTcy8vG1fToLT/openapi.json
