# GitHub Scraper: Repos, Owners, Issues & Contributors (`glitchbound/github-scraper`) Actor

Search GitHub repositories with the full search syntax, or pull specific repos, whole organisations and user profiles. Returns stars, forks, language, topics, license, activity dates, plus optional contributors and issues. Official GitHub API: a token is optional, not required.

- **URL**: https://apify.com/glitchbound/github-scraper.md
- **Developed by:** [Daniel Meshulam](https://apify.com/glitchbound) (community)
- **Categories:** Developer tools, Automation, Lead generation
- **Stats:** 2 total users, 1 monthly users, 100.0% runs succeeded, 0 bookmarks
- **User rating**: No ratings yet

## Pricing

from $0.75 / 1,000 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/platform/actors/running/actors-in-store#pay-per-event

## What's an Apify Actor?

Actors are web data automations that power AI and operations. They run on the Apify platform to scrape websites, process data, connect APIs, and automate workflows.
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.
Actors are written with capital "A".

## 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.
The best way to integrate Actors is as follows.

- **AI agents and MCP clients** — the [Apify MCP server](https://docs.apify.com/integrations/mcp.md) at `https://mcp.apify.com` (remote, streamable HTTP, OAuth on first use).
- **Agentic workflows and local Actor development** — [Agent Skills](https://apify.com/.well-known/agent-skills/index.json) with the [Apify CLI](https://docs.apify.com/cli/docs.md): `npm install -g apify-cli`, then `apify login`.
- **JavaScript/TypeScript projects** — the official [JS/TS client](https://docs.apify.com/api/client/js/docs.md): `npm install apify-client`.
- **Python projects** — the official [Python client](https://docs.apify.com/api/client/python/docs.md): `pip install apify-client`.
- **Any other language** — the [REST API](https://docs.apify.com/api/v2.md).

For usage examples, see the [API](#api) section below.

For more details, see Apify documentation as [Markdown index](https://docs.apify.com/llms.txt) and [Markdown full-text](https://docs.apify.com/llms-full.txt).

# README

## GitHub Scraper: Repos, Owners, Issues & Contributors

Search GitHub the way GitHub search works, and get structured rows back.

```json
{ "searchQueries": ["topic:web-scraping stars:>500"], "sortBy": "stars" }
```

No token required. Give it one and it goes faster, see below.

### Four ways in

| Input | What you get |
|---|---|
| `searchQueries` | full GitHub search syntax: `language:rust stars:>1000`, `org:apify archived:false`, `topic:mcp pushed:>2026-01-01` |
| `repositories` | specific repos as `owner/name` |
| `owners` | every public repo of a user **or** an organisation, you do not have to know which |
| `users` | profile details: name, company, location, followers, public email if published |

Turn on `includeContributors` or `includeIssues` and every repo in
`repositories` also returns its contributors ranked by commits, or its issues
and pull requests newest-activity-first.

### The rate limit, stated plainly

Unauthenticated GitHub allows **60 requests per hour per IP**. Every Actor in
this niche hits it; most just fail and blame the network.

Two things are done about it here:

1. **Proxy rotation on exhaustion.** GitHub answers with `403` and
   `x-ratelimit-remaining: 0`. That triggers a new IP, and a new IP has a fresh
   60\. A run keeps going instead of dying at request 61.
2. **Pages of 100.** Every list request asks for GitHub's maximum page size, so
   one request returns 100 rows instead of the default 30. Three times fewer
   requests against the same limit.

When it genuinely runs out, you get one `error` row that says so and names the
fix, not a silent empty dataset.

**With a token** (`githubToken`) the limit becomes **5,000 requests per hour**.
Create one at *Settings → Developer settings → Personal access tokens*; no
scopes are needed for public data. It is sent to `api.github.com` and nowhere
else, is marked secret in the input schema, and never appears in a result row.

### Output

Every row carries `recordType`, so a mixed run stays sortable:

- `repo`, full name, owner, description, language, stars, forks, watchers, open issues, topics, license, size, `createdAt` / `updatedAt` / `pushedAt`, archived and fork flags
- `user`, login, name, company, location, blog, bio, followers, following, public repo count, hireable
- `contributor`, login, commit count, profile URL
- `issue` / `pull_request`, number, title, state, author, labels, comment count, body

### Use cases

- **Developer lead generation**: find maintainers of repos using your competitor's SDK
- **Competitive and OSS research**, who is building in your space, and is it still maintained (`pushedAt`, `isArchived`)
- **Dependency and supply-chain review**: license, activity and contributor concentration per repo
- **Hiring**: search by language and topic, then pull profiles
- **AI agents**: clean JSON over the API, no HTML parsing

### Pricing

Charged per row returned. A repo that does not exist, a query GitHub rejects, or
an exhausted rate limit produces an `error` row and costs **$0.00**.

### Do you need an API key? No. Is there a free tier? Yes.

The two things people search for in this category, measured, are **free** and
**API key**: `github api key scraper`, `github openai api key scraper`.

So, plainly:

- **No API key.** Nothing to register for, nothing to rotate, no key to leak in
  a repo. A GitHub token is optional and only raises the rate limit from 60 to 5,000 requests an hour on large runs. Everything works without one.
- **No proxy setup.** The source does not bot-wall datacenter addresses, so the
  default works.
- **Pay per result, not per month.** There is no subscription and no minimum.
  Rows that error or that your filters drop are **not charged**.
- **Free to try.** Run it with the prefilled input and see real rows before
  deciding anything.

### Notes

- Only public data. `email` appears solely when the user has chosen to publish it
  on their profile; nothing is inferred, guessed or assembled from commits.
- GitHub caps any single search at **1,000 results** regardless of `maxResultsPerQuery`. Narrow the query, by language, by star range, by date, to go past it.
- `owners` tries the organisation endpoint first and falls back to the user one, so it works either way without you knowing which the login is.

### FAQ

#### Do I need a GitHub token?

No. It works unauthenticated. GitHub's unauthenticated limit is 60 requests per
hour per IP, which this handles by rotating proxy IPs on exhaustion and asking for
100-row pages. Supplying `githubToken` raises the limit to 5,000 requests per
hour and is worth it for large runs.

#### What scopes does the token need?

None. A classic personal access token with no scopes ticked is enough for public
data. Create one at *Settings → Developer settings → Personal access tokens*. It
is sent to `api.github.com` and nowhere else, is marked secret in the input
schema, and never appears in a result row.

#### Can I use the same search syntax as GitHub's own search box?

Yes, that is the point of `searchQueries`. `language:rust stars:>1000`,
`topic:mcp pushed:>2026-01-01`, `org:apify archived:false` all work exactly as
they do on github.com.

#### Why do I get fewer than 1,000 results?

GitHub caps any single search at 1,000 results no matter what you set
`maxResultsPerQuery` to. Split the query by language, by star range or by push
date to get past it. That is a GitHub limit, not an Actor one.

#### Do I have to know whether a login is a user or an organisation?

No. `owners` tries the organisation endpoint first and falls back to the user
endpoint, so it returns every public repo either way.

#### Can I get contributor email addresses?

`email` appears only when the user has chosen to publish it on their public
profile. Nothing is inferred, guessed, or assembled out of commit metadata.

#### How do I tell whether a project is still maintained?

`pushedAt` and `isArchived` on every repo row. `pushedAt` is the last push to any
branch, which is a far better liveness signal than `updatedAt`, which moves
when someone merely stars the repo.

# Actor input Schema

## `searchQueries` (type: `array`):

GitHub search syntax, one per line. Examples: language:python stars:>1000 · topic:mcp pushed:>2026-01-01 · org:apify archived:false

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

Specific repos as owner/name, e.g. apify/crawlee. You can paste the URL instead of the identifier, e.g. https://github.com/torvalds/linux works.

## `owners` (type: `array`):

Every public repo belonging to these logins. Works for both users and organisations.

## `users` (type: `array`):

Profile details for these logins: name, company, location, followers, and the contact email only if the user chose to publish it.

## `sortBy` (type: `string`):

Applies to search queries only.

## `maxResultsPerQuery` (type: `integer`):

Cap per query, per owner, and per issue/contributor list. GitHub itself caps search at 1,000.

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

For each repo in Repositories, also return its contributors ranked by commit count.

## `includeIssues` (type: `boolean`):

For each repo in Repositories, also return issues and PRs, newest activity first.

## `issueState` (type: `string`):

Which issues and pull requests to return when Include issues is on.

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

A personal access token raises GitHub's limit from 60 to 5,000 requests per hour. Only needed for large runs. It is sent to api.github.com and nothing else, and never appears in the output.

## `proxyConfiguration` (type: `object`):

Proxy settings. Rotation is what keeps unauthenticated runs alive, since each new IP gets a fresh hourly quota.

## `maxItems` (type: `integer`):

A hard ceiling on rows for the entire run, across every target. The per-target limits above cap each one separately, so fifty targets at twenty each is still a thousand rows; this caps the total. The run stops cleanly when it is reached and nothing beyond that point is fetched or charged. Leave empty for no ceiling.

## Actor input object example

```json
{
  "searchQueries": [
    "topic:web-scraping stars:>500"
  ],
  "sortBy": "stars",
  "maxResultsPerQuery": 100,
  "includeContributors": false,
  "includeIssues": false,
  "issueState": "open",
  "proxyConfiguration": {
    "useApifyProxy": true
  }
}
```

# Actor output Schema

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

Repos with stars, forks, topics and license; users with followers and company; contributors and issues when requested.

# 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 = {
    "searchQueries": [
        "topic:web-scraping stars:>500"
    ]
};

// Run the Actor and wait for it to finish
const run = await client.actor("glitchbound/github-scraper").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 = { "searchQueries": ["topic:web-scraping stars:>500"] }

# Run the Actor and wait for it to finish
run = client.actor("glitchbound/github-scraper").call(run_input=run_input)

# Fetch and print Actor results from the run's dataset (if there are any)
print("💾 Check your data here: https://console.apify.com/storage/datasets/" + run["defaultDatasetId"])
for item in client.dataset(run["defaultDatasetId"]).iterate_items():
    print(item)

# 📚 Want to learn more 📖? Go to → https://docs.apify.com/api/client/python/docs/quick-start

```

## CLI example

```bash
echo '{
  "searchQueries": [
    "topic:web-scraping stars:>500"
  ]
}' |
apify call glitchbound/github-scraper --silent --output-dataset

```

## MCP server setup

```json
{
    "mcpServers": {
        "apify": {
            "command": "npx",
            "args": [
                "mcp-remote",
                "https://mcp.apify.com/?tools=glitchbound/github-scraper",
                "--header",
                "Authorization: Bearer <YOUR_API_TOKEN>"
            ]
        }
    }
}

```

## OpenAPI specification

Download the OpenAPI definition: https://api.apify.com/v2/acts/eAyGLs7nZ1Loyqkf5/builds/mfuVf61JT92UxLHwd/openapi.json
