# GitHub Repo Search: Topic / Language / Date | $2/1K (`cleanfeedsapi/github-repo-search`) Actor

Official GitHub Search API → new and trending public repos by topic, language, or created:>date window. Stars, forks, license, topics, owner. Optional token for higher rate limit. No HTML scrape, no proxies. $2 per 1,000 repos.

- **URL**: https://apify.com/cleanfeedsapi/github-repo-search.md
- **Developed by:** [CleanFeeds API](https://apify.com/cleanfeedsapi) (community)
- **Categories:** Developer tools
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $1.00 / 1,000 repo rows

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 Repo Search: Topic / Language / Date | $2/1K

**Quick start**

- GitHub repo search API as a dataset: one JSON row per public repository matching each query, with stars, forks, language, topics, license, timestamps and owner.
- Minimal input: `{"queries": ["topic:mcp stars:>50"]}`
- Run it from the Console, the API, or the Apify MCP server; export JSON, CSV or Excel.

Find **new and trending public GitHub repositories** by topic, language, or date window via the **official GitHub REST Search API**. No HTML scraping, no login wall, no proxies. Pass the same query syntax you use on github.com/search (`topic:mcp`, `language:Rust`, `created:>2026-10-01`).

You get one dataset row per repo: full name, URL, description, language, stars, forks, open issues, topics, license, created/updated/pushed timestamps, archived flag, owner.

### Why this instead of scraping or the vendor API

- It is the vendor API, with the plumbing done. The Actor calls `GET https://api.github.com/search/repositories` with `per_page=100` and pages through the results, so you get a flat dataset instead of writing pagination and rate-limit code.
- The Search API caps every query at 1,000 results (10 pages of 100). The Actor stops there and says so. To cover more, split one broad query into several narrow ones (`stars:>500`, `stars:100..500`, monthly `created:` windows) and pass them all in `queries`.
- Rate limits are respected, not fought. Unauthenticated search allows 10 requests per minute, 30 with a token. The Actor reads `X-RateLimit-Remaining` and `X-RateLimit-Reset` and sleeps until reset when the budget hits zero, then continues.
- Optional token, never required. Pass a personal access token in the secret `token` field only when you run many pages or many queries.
- The github.com trending page has no API and changes daily with no history. A scheduled run of `created:>` or `pushed:>` queries gives you a reproducible dataset per day.

### What you get

| Field | Meaning |
|---|---|
| `query` | the search string that produced this row |
| `full_name` | `owner/repo` |
| `url` | `https://github.com/owner/repo` |
| `description` | repo description (or `null`) |
| `language` | primary language (or `null`) |
| `stars`, `forks`, `open_issues` | counts from the Search API |
| `topics` | string array of topic tags |
| `license` | SPDX id when GitHub knows it (else `null`) |
| `created_at`, `updated_at`, `pushed_at` | ISO 8601 |
| `archived` | boolean |
| `owner`, `owner_type` | login + `User` / `Organization` |

A query that fails (bad syntax, HTTP error) does **not** abort the run: it yields one row with `query` and `error`, and other queries continue.

**Not included, by design:** profile / follower scraping, private repos, code search, commit contents, README bodies. This Actor is a narrow **repo discovery feed** for topic/language/date windows.

### Input examples

```json
{ "queries": ["topic:mcp stars:>50"], "sort": "stars", "maxReposPerQuery": 200 }
```

```json
{
  "queries": [
    "created:>2026-10-01 language:Rust",
    "topic:llm stars:>100 pushed:>2026-09-01"
  ],
  "sort": "updated",
  "maxReposPerQuery": 100
}
```

| Field | Type | Default | Notes |
|---|---|---|---|
| `queries` | string list | `topic:mcp stars:>50` | GitHub search syntax |
| `sort` | enum | `stars` | `stars` | `updated` | `forks` |
| `maxReposPerQuery` | integer | `200` | hard-capped at **1000** (GitHub Search API limit); `0` = 1000 |
| `token` | secret string | empty | optional PAT; raises Search rate limit 10 to 30 req/min |

### Output example

```json
{
  "query": "topic:mcp stars:>50",
  "full_name": "modelcontextprotocol/servers",
  "url": "https://github.com/modelcontextprotocol/servers",
  "description": "Model Context Protocol Servers",
  "language": "TypeScript",
  "stars": 12000,
  "forks": 1500,
  "open_issues": 80,
  "topics": ["mcp", "ai"],
  "license": "MIT",
  "created_at": "2024-11-19T00:00:00Z",
  "updated_at": "2026-11-01T12:00:00Z",
  "pushed_at": "2026-11-01T11:30:00Z",
  "archived": false,
  "owner": "modelcontextprotocol",
  "owner_type": "Organization"
}
```

### How much does it cost?

Pay per event: **$2.00 per 1,000 repo rows** (`repo` event, $0.002 each) plus Apify's small Actor-start event. Platform compute is on us. Set a maximum charge per run in the Console and the Actor stops at the limit. The Apify free plan is enough to try the sample query.

### Rate limits

GitHub Search API: **10 req/min** unauthenticated, **30 req/min** with a token. This Actor reads `X-RateLimit-Remaining` / `X-RateLimit-Reset` and sleeps until reset when remaining hits 0. Max **1000 results per query** (GitHub hard cap, 10 pages × 100).

### Use cases

- **Trend / launch radar**: `created:>YYYY-MM-DD language:...` or `topic:...` daily, catch new repos in a niche.
- **Competitive / ecosystem maps**: dump top starred repos for a topic into a sheet.
- **AI agents / MCP**: "list hot Rust repos this month" without browser automation.
- **Monitoring**: schedule weekly, diff `full_name` sets for newcomers above a stars threshold.

### Integrations

- **Apify API**: `POST https://api.apify.com/v2/acts/cleanfeedsapi~github-repo-search/run-sync-get-dataset-items?token=<APIFY_TOKEN>` with the input JSON as the body. The response is the dataset, ready to parse.
- **Scheduling**: open the Actor in the Apify Console, click Schedule, pick a cron (for example weekly on Monday) and the saved input runs on its own. Each run keeps its own dataset.
- **n8n, Make, Zapier**: use the Apify integration in each tool, choose this Actor and pass the same input JSON. No per-Actor setup, no custom code.
- **Apify MCP server for AI agents**: connect the Apify MCP server to Claude, Cursor or any MCP client and ask the agent to run `cleanfeedsapi/github-repo-search` with these inputs.

### Related Actors by CleanFeeds

- [hn-who-is-hiring](https://apify.com/cleanfeedsapi/hn-who-is-hiring): monthly Hacker News hiring thread as structured rows.
- [steam-store-games](https://apify.com/cleanfeedsapi/steam-store-games): Steam storefront details, search and listings.
- [app-store-reviews](https://apify.com/cleanfeedsapi/app-store-reviews): Apple App Store customer reviews via the public RSS JSON.
- [shopify-products-feed](https://apify.com/cleanfeedsapi/shopify-products-feed): Shopify storefront `products.json` with a change filter.
- [domain-mx-preflight](https://apify.com/cleanfeedsapi/domain-mx-preflight): MX, A and HTTPS preflight for domain lists.

More feeds at [cleanfeeds.dev](https://cleanfeeds.dev).

### FAQ

**Do I need a GitHub token?** No. Unauthenticated works (10 Search req/min). Add a token only if you run many pages or many queries.

**Is this HTML scraping?** No. Only `GET https://api.github.com/search/repositories`.

**Can I get more than 1000 repos for one query?** No. That is GitHub's Search API ceiling. Narrow the query (`stars:>N`, date windows) instead.

**Why is `license` null?** GitHub did not detect a license file for that repo.

**One query 422s, what happens?** You get one `error` row for it; other queries still run.

**How do I detect new and closed items between runs?** `full_name` (`owner/repo`) is the stable key. Keep each run's dataset and compare `full_name` sets per `query`: names present today but not last week are newcomers; names that dropped out were renamed, deleted, archived out of the filter, or fell below your `stars:` threshold. Check `archived` on the newer run before calling a repo gone.

**What happens when a source fails?** A query that GitHub rejects (422 for bad syntax, 5xx, or a rate-limit 403 without a reset header) does not stop the run. The Actor logs it, pushes one row with `query` and `error` (status, URL and the first 200 characters of GitHub's response), and moves to the next query. Error rows are not charged. A 403 with `X-RateLimit-Remaining: 0` is not an error: the Actor sleeps until reset and retries the same page.

# Actor input Schema

## `queries` (type: `array`):

GitHub search syntax, e.g. topic:mcp stars:>50, created:>2026-10-01 language:Rust, pushed:>2026-09-01 stars:>100. Same qualifiers as github.com/search.

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

stars | updated | forks

## `maxReposPerQuery` (type: `integer`):

Capped at GitHub Search API limit of 1000 results per query. 0 = 1000.

## `token` (type: `string`):

Personal access token (classic or fine-grained with public_repo read). Raises Search rate limit from 10 to 30 req/min. Leave empty for unauthenticated.

## Actor input object example

```json
{
  "queries": [
    "topic:mcp stars:>50"
  ],
  "sort": "stars",
  "maxReposPerQuery": 200
}
```

# Actor output Schema

## `repos` (type: `string`):

Default dataset with all repo rows (query, full_name, url, description, language, stars, forks, open_issues, topics, license, dates, archived, owner, owner_type).

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

Key-value store record SUMMARY: {queries, repos} counts for the run.

# 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 = {
    "queries": [
        "topic:mcp stars:>50"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("cleanfeedsapi/github-repo-search").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 = { "queries": ["topic:mcp stars:>50"] }

# Run the Actor and wait for it to finish
run = client.actor("cleanfeedsapi/github-repo-search").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 '{
  "queries": [
    "topic:mcp stars:>50"
  ]
}' |
apify call cleanfeedsapi/github-repo-search --silent --output-dataset

```

## MCP server setup

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

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/GF5rHJ9lCIv8jZMiZ/builds/oMLL7GNJx7NtEBtOJ/openapi.json
