# SiteVerdict — GitHub Repo Analytics & Star History (`siteverdict/siteverdict-github-repo-analytics`) Actor

Compare GitHub repos with the official API: stars, forks, open issues vs PRs, PR merge speed, issue close time, contributors, releases and commit activity. Org scans, growth tracking and alerts for star spikes and new releases. Token optional; star history needs one.

- **URL**: https://apify.com/siteverdict/siteverdict-github-repo-analytics.md
- **Developed by:** [Aman Thakran](https://apify.com/siteverdict) (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

Pay per event

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

## SiteVerdict — GitHub Repo Analytics & Star History

**Is your open-source project winning? Compare it with competitors on the numbers that matter: momentum, maintainer speed and community, not just stars.** One row per repository from the official GitHub API: stars and a sampled star history, forks, open issues vs open PRs, PR merge speed, issue close time, contributors, releases and commit activity. Run it on a schedule to track growth between runs and get Slack/webhook alerts for star spikes and new releases.

### Who it is for

- **Open-source maintainers and DevRel**: weekly benchmark against alternatives.
- **Investors and analysts**: momentum and health signals for many repos or whole orgs.
- **Developer-tool marketers**: see when a competitor ships a release or goes viral.
- **AI agents**: "compare these repos" with real, current numbers (see `MCP-TOOL.md`).

### What you get per repository

| Field | Meaning |
|---|---|
| `stars`, `forks`, `watchers` | current totals |
| `starsGained30d`, `starsGained90d`, `starHistory[]` | sampled from the stargazers API (marked estimated for >40k stars) |
| `starsSinceLastRun`, `stars7dTracked`, `stars30dTracked` | exact deltas from your own run history |
| `openIssues`, `openPrs` | open issues and PRs split (GitHub's own counter mixes them) |
| `prsOpened30d`, `prsMerged30d`, `prsClosedUnmerged30d`, `medianHoursToMerge` | PR velocity (bot PRs excluded) |
| `issuesOpened30d`, `issuesClosed30d`, `medianHoursToCloseIssue` | issue responsiveness |
| `contributors` | contributor count (usernames only if you enable `includeContributors`) |
| `latestRelease`, `daysSinceLastRelease`, `releases90d` | release cadence |
| `commits12w`, `commits52w`, `daysSinceLastPush`, `archived` | activity and risk |
| `alerts[]` | `sample-org/fast-router gained 400 stars since the last run (18020 → 18420).` |

Org scan rows (`type: "org-repo"`) list every public repo with stars, forks, language and last push, and the top N get the full report. Exports: `REPORT.html`, `repos.csv`, `SUMMARY`.

### Use cases

1. **Competitor benchmark**: `{"repos": ["you/your-lib", "rival/lib-a", "rival/lib-b"]}` weekly, HTML report to the team.
2. **Org health review**: `{"orgs": ["your-org"], "deepAnalyseTopN": 10}` to find stale or overloaded repos.
3. **Launch radar**: daily run over 30 competitor repos with `alertOnRelease` and Slack.

### Token and limits

- **No token:** 60 GitHub API requests/hour per IP, so the default budget is 55 calls (about 4–5 full reports per run).
- **With a token** (fine-grained, public repositories read-only is enough): 5,000 requests/hour; default budget 1,000 calls.
- A full report costs about 9–14 calls (6 for the star curve, configurable). The Actor reads GitHub's rate-limit headers and stops cleanly before the limit, reporting what it skipped.

### Pricing (pay per event)

| Event | Price | When |
|---|---|---|
| `repo-report` | $0.01 | one full repository report |
| `org-repo` | $0.002 | one org scan row |
| `repo-alert` | $0.01 | one alert |
| `ai-brief` | $0.03 | AI comparison with your own key (only on success) |

Examples: 10 repos weekly = $0.10/week; an org with 300 repos + top 10 deep = $0.70. Not-found repos and rate-limit stops are free. Sample mode is free.

### FAQ

**Do I need a GitHub token?** No for most metrics. Star history is the exception: since October 2026 GitHub answers the stargazers list with HTTP 401 unless you are signed in, so without a token the star-history fields are empty and `starHistoryNote` explains why. A free read-only token fixes it and raises the limit from 60 to 5,000 requests/hour.

**How accurate is star history?** The stargazers API returns stars in order with timestamps; we sample a few pages and interpolate, which is accurate for trends. GitHub only serves the first 40,000 stargazers, so curves for bigger repos are marked as estimates. Your own run history (`starsSinceLastRun`) is exact.

**Private repos?** Not supported: public data only.

**Why are commit counts sometimes empty?** GitHub computes statistics in the background for rarely viewed repos (HTTP 202); they appear on the next run.

### Limits

- PR/issue velocity looks at the most recent 100 PRs and issues updated in 30 days; extremely busy repos are sampled.
- Contributor counts follow GitHub's contributors endpoint (top 500 attributed to accounts).

### Sources & compliance

- Source: GitHub REST API (`api.github.com`, version 2022-11-28), read-only GETs, under the GitHub Terms of Service and API terms (https://docs.github.com/en/site-policy/github-terms/github-terms-of-service, section H "API Terms"; checked 11 Oct 2026). Rate limits and headers respected; no scraping of github.com.
- **Personal data off by default:** contributor usernames are not output unless enabled; no emails are collected. UK GDPR: usernames are public but personal data; enable only if you need them. PECR: no messaging is performed.
- Tokens, webhook URLs and AI keys are secret inputs, redacted from logs and outputs. Webhooks are HTTPS-only and SSRF-guarded.
- Not affiliated with GitHub.

# Changelog

This Actor's version history is a separate document: https://apify.com/siteverdict/siteverdict-github-repo-analytics/changelog.md

# Actor input Schema

## `executionMode` (type: `string`):

<b>live</b>: call the GitHub API. <b>sample</b>: synthetic repositories with history (shows alerts; no calls, nothing charged).

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

owner/name or github.com URLs (max 100). Put your repo and your competitors here.

## `orgs` (type: `array`):

Lists their public repositories (one cheap row each, sorted by stars) and deep-analyses the top N.

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

A fine-grained or classic token with public read access only. Raises the limit from 60 to 5,000 requests/hour. Never logged or output.

## `maxReposPerOrg` (type: `integer`):

Org scan size (100 per API call).

## `deepAnalyseTopN` (type: `integer`):

Full report (PRs, issues, contributors, releases, star history) for the most-starred non-fork repos of each org.

## `starHistory` (type: `boolean`):

Sample the stargazers API to build a star curve and stars gained in 30/90 days. Needs a GitHub token: GitHub refuses the stargazers list to anonymous requests (without a token the rows say so and every other metric still works).

## `starHistorySamples` (type: `integer`):

API calls per repo for the star curve (more = smoother).

## `commitActivity` (type: `boolean`):

Commits in the last 12 and 52 weeks (GitHub may need a second run to compute stats for rarely viewed repos).

## `includeContributors` (type: `boolean`):

Off by default (usernames are personal data). Counts are always included.

## `maxApiCalls` (type: `integer`):

Defaults to 55 without a token and 1,000 with one. A deep report costs about 9-14 calls.

## `starAlertMin` (type: `integer`):

Alert when a repo gains at least this many stars since the previous run.

## `starAlertPct` (type: `integer`):

…or at least this percentage (and 5+ stars).

## `alertOnRelease` (type: `boolean`):

Alert when the latest release tag changes.

## `webhookUrl` (type: `string`):

Optional JSON POST with alerts. Private and internal addresses are blocked.

## `slackWebhookUrl` (type: `string`):

Optional. https://hooks.slack.com/services/...

## `stateStoreName` (type: `string`):

Named key-value store for growth tracking between runs.

## `aiProvider` (type: `string`):

Off by default. A comparison briefing with a verdict per repo, written from this run's metrics with YOUR Anthropic or OpenAI key.

## `aiApiKey` (type: `string`):

Your own Anthropic or OpenAI API key. Never logged or output.

## `aiModel` (type: `string`):

Defaults: claude-sonnet-5-5 (Anthropic) or gpt-4o-mini (OpenAI).

## Actor input object example

```json
{
  "executionMode": "live",
  "repos": [
    "apify/crawlee",
    "microsoft/playwright"
  ],
  "maxReposPerOrg": 100,
  "deepAnalyseTopN": 5,
  "starHistory": true,
  "starHistorySamples": 6,
  "commitActivity": true,
  "includeContributors": false,
  "starAlertMin": 50,
  "starAlertPct": 5,
  "alertOnRelease": true,
  "stateStoreName": "siteverdict-github-history",
  "aiProvider": "none"
}
```

# Actor output Schema

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

No description

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

No description

## `files` (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 = {
    "executionMode": "live",
    "repos": [
        "apify/crawlee",
        "microsoft/playwright"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("siteverdict/siteverdict-github-repo-analytics").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 = {
    "executionMode": "live",
    "repos": [
        "apify/crawlee",
        "microsoft/playwright",
    ],
}

# Run the Actor and wait for it to finish
run = client.actor("siteverdict/siteverdict-github-repo-analytics").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 '{
  "executionMode": "live",
  "repos": [
    "apify/crawlee",
    "microsoft/playwright"
  ]
}' |
apify call siteverdict/siteverdict-github-repo-analytics --silent --output-dataset

```

## MCP server setup

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

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/afLmLwNlSlnANJuB6/builds/HnvTvXDepZxXZCceW/openapi.json
