GitHub Scraper | Repositories, Issues & Profiles
Pricing
from $2.20 / 1,000 results
GitHub Scraper | Repositories, Issues & Profiles
Extract public GitHub repositories, issues, pull requests, users and topic or organization listings. Export metadata and available public profile details. Pay per delivered row plus a start fee. Unofficial; not affiliated with GitHub.
Pricing
from $2.20 / 1,000 results
Rating
0.0
(0)
Developer
kane liu
Maintained by CommunityActor stats
1
Bookmarked
5
Total users
2
Monthly active users
35 minutes ago
Last modified
Categories
Features
Share
Extract public GitHub repositories, issues, pull requests and profiles as structured rows you can export or use through the API.
- Find repositories by search query, topic or organization.
- Collect issue and pull-request titles, numbers, states and links.
- Add public profile names, location text, websites and published emails.
- Export JSON, CSV or Excel without supplying a GitHub personal access token.
- Pay $3.00 per 1,000 delivered rows on the Free plan, plus a start fee.
What does GitHub Scraper do?
GitHub Scraper collects public metadata from github.com for repository research, issue monitoring and organization inventories. It does not download source files or private repositories. It is unofficial and is not affiliated with GitHub.
- Search: repositories, issues, pull requests and users; discussion search is also offered but may return no rows.
- Lists: repositories under a topic or organization, and issues within a repository.
- Details: one repository or issue, identified by its URL or identifiers.
- Profile enrichment:
enrichDetailsdefaults totrue. It adds available public profile fields to existing rows, not separate billable rows.
What data can you extract from GitHub?
Fields depend on the selected mode and what GitHub publishes. Each row represents one entity. kind distinguishes the row types below. Examples are illustrative, not current measurements.
Common identity and profile fields
| Field | Description | Example |
|---|---|---|
id | Source ID, or an identifier derived from the entity | 123456 |
name | Repository name, title or user display name (null if none) | psf/requests |
url | Link to the entity | https://github.com/psf/requests |
kind | Row type | repository |
status | Listing status or issue state | listed |
country | Source market; not the person's location | US |
person.name | Public display name or login fallback | Jane Doe |
org.name | Organization name or profile company text | Example Organization |
emails | Public email objects; often empty | [{"value":"name@example.com","type":"public"}] |
address.full | Public location text, not a street address | Example City |
web.website | Profile website or repository homepage | https://example.com |
web.socials | Published social links | [] |
leadAbsences | Reasons unavailable contact fields are empty | {"phones":{"reason":"not_verified (field not on this public surface)","surface":"github.com"}} |
Repository rows: repository or repo
| Field | Description | Example |
|---|---|---|
fullName | Owner and repository name | psf/requests |
ownerLogin | Repository owner's login | psf |
language | Primary language, when present | Python |
stargazerCount | Published star count | 50000 |
forkCount | Published fork count, when present | 1000 |
topics | Repository topics, when present | ["python"] |
license | License identifier, when present | Apache-2.0 |
updatedAt | Source update time, when present | 2026-10-20T12:00:00Z |
Issue rows: issue
| Field | Description | Example |
|---|---|---|
number | Issue number within its repository | 123 |
name | Issue title | Example documentation issue |
status | Issue state | open |
numComments | Comment count, not comment bodies | 4 |
author | Public author login | example-user |
Pull-request rows: pullrequest
| Field | Description | Example |
|---|---|---|
number | Pull-request number | 124 |
name | Pull-request title | Update documentation |
status | Open or closed state | closed |
merged | Merge indicator when available | true |
Discussion rows: discussion
| Field | Description | Example |
|---|---|---|
number | Discussion number when returned | 125 |
name | Discussion title | Example usage question |
numComments | Published comment count | 2 |
User rows: user
| Field | Description | Example |
|---|---|---|
login | Public account login | example-user |
person.name | Display name or login fallback | Jane Doe |
address.full | Public location text | Example City |
Topic repository rows: topicRepo
| Field | Description | Example |
|---|---|---|
topic | Topic used for the list | python |
fullName | Listed repository | psf/requests |
stargazerCount | Star count when available | 50000 |
Organization repository rows: orgRepo
| Field | Description | Example |
|---|---|---|
fullName | Organization and repository name | microsoft/vscode |
isFork | Whether the repository is a fork | false |
language | Primary language | TypeScript |
How to scrape GitHub
- Open GitHub Scraper in Apify Console.
- Enter a
queryordetailUrls; for identifier-based requests, choosesearchTypeand fill the matching fields below. - Set
maxResultsto3for a small first run. - Click Start and wait for completion.
- Open the dataset and download your rows.
Empty input {} runs the form's example: query is stars:>50000, searchType is repositories, and the limit is 3 rows. Normal event prices apply. A query alone uses repository search. Filling org or owner and repo alone does not select their modes; set searchType explicitly.
Repository search
Use repositories with a query such as language:python crawler. GitHub search qualifiers can narrow the matches.
Issue search
Use issues with a query. Add repo:owner/name to restrict the search to one repository.
Pull-request search
Use pullrequests with a query. This returns search metadata, not diffs or full pull-request pages.
Discussion search
Use discussions with a query. This option may return no indexed matches; it is not a complete discussion archive.
User search
Use users with a query. Leave enrichDetails enabled for available public profile information.
Topic repositories
Use topic with the topic slug in query, such as python.
Organization repositories
Use orgRepos with a real organization login in org.
One repository
Use repo with both owner and repo. The output is metadata, not repository contents.
One issue
Use issue with owner, repo and an existing issueNumber copied from GitHub.
Repository issue list
Use issuesList with owner and repo. This list can include pull requests; inspect kind to distinguish them.
Direct URLs
Put supported repository, issue, organization-repository or topic links in detailUrls. Their paths determine the page type. Links without https:// are accepted. Pull-request detail URLs, issue-list URLs and other websites are rejected. Use the matching mode above for repository issue lists.
What to fill in
| Field | What to enter | Default |
|---|---|---|
query | Search text, or topic slug for topic | No schema default; example stars:>50000 |
searchType | Mode described above | repositories |
detailUrls | Array of supported GitHub links | Empty |
owner | Repository owner login | Empty |
repo | Repository name, without owner | Empty |
issueNumber | Existing positive issue number | Empty |
org | Organization login for orgRepos | Empty |
language | Language filter for searches | Empty |
repoType | all, public, source, fork, archived or template | Empty, meaning all |
sort | Supported search sort, such as stars | Empty |
order | Search order, such as desc | Empty |
maxResults | Most rows per input, from 1 to 200 | 70; form example 3 |
maxPages | Page limit, from 1 to 100 | 1 |
enrichDetails | Add available public profile fields | true |
Repository search:
{"query":"language:python crawler","searchType":"repositories","maxResults":3}
Issue search:
{"query":"repo:psf/requests documentation","searchType":"issues","maxResults":3}
Pull-request search:
{"query":"repo:psf/requests documentation","searchType":"pullrequests","maxResults":3}
Discussion search:
{"query":"python","searchType":"discussions","maxResults":3}
User search:
{"query":"type:org python","searchType":"users","maxResults":3}
Topic repositories:
{"query":"python","searchType":"topic","maxResults":3}
Organization repositories:
{"searchType":"orgRepos","org":"microsoft","repoType":"public","maxResults":3}
One repository:
{"searchType":"repo","owner":"psf","repo":"requests","maxResults":1}
One issue; replace the number with an existing issue:
{"searchType":"issue","owner":"psf","repo":"requests","issueNumber":1,"maxResults":1}
Repository issue list:
{"searchType":"issuesList","owner":"psf","repo":"requests","maxResults":3}
Direct URLs:
{"detailUrls":["github.com/psf/requests","github.com/microsoft/vscode"],"maxResults":1}
maxItemsandlimitare aliases formaxResults.qandkeywordmap toquery;urlsandstartUrlsmap todetailUrls.- Unknown fields do not fail the run. Close misspellings are corrected when possible; other unknown fields are ignored with a note.
- The
INPUT_REPORTrecord in the default key-value store records normalization, filled fields, ignored fields and errors. - Invalid links and unrecognized mode values produce
INVALID_INPUT: <field> — <how to fix>before any row is charged. The start fee still applies. Invalid optionalrepoTypevalues are ignored with a warning instead.
Output example
Illustrative repository row; counts and timestamps are examples:
{"id": 123456,"kind": "repository","type": "repository","name": "psf/requests","fullName": "psf/requests","ownerLogin": "psf","url": "https://github.com/psf/requests","status": "listed","country": "US","authority": "github.com","language": "Python","stargazerCount": 50000,"forkCount": 1000,"topics": ["python"],"emails": [],"phones": [],"updatedAt": "2026-10-20T12:00:00Z"}
You can export the dataset as JSON, CSV, Excel, XML, RSS or an HTML table.
Why use this GitHub scraper?
- Pay for delivered rows. Row charges apply to dataset rows, not unsuccessful attempts.
- Keep delivered data. Rows already written to the dataset remain available after a stop. Collection interrupted before delivery may produce no dataset rows.
- Understand failures. Input errors identify the problem;
ERROR_SUMMARYrecords failures andRUN_SUMMARYrecords completed runs. - See missing information. Unavailable contact details remain empty rather than being invented.
- Process several URLs. Supply multiple supported links in
detailUrls. - Less setup. You do not need to set up proxies or supply a GitHub account, cookies or personal access token.
How much does it cost to scrape GitHub?
The Actor uses pay-per-event pricing. A start event costs $0.005 per GB of memory, with a minimum of one event. Default memory is 1024 MB, so a normal start costs $0.005. Platform usage is included in these prices.
| Apify plan | Start at 1024 MB | Price per row | Price per 1,000 rows |
|---|---|---|---|
| Free | $0.005 | $0.003 | $3.00 |
| Starter | $0.005 | $0.003 | $3.00 |
| Scale | $0.005 | $0.0026 | $2.60 |
| Business | $0.005 | $0.0022 | $2.20 |
| Platinum | $0.005 | $0.002 | $2.00 |
| Diamond | $0.005 | $0.0016 | $1.60 |
maxResultsapplies to each detail URL or to the single query, topic, organization, repository or issue input. Its default is 70; larger requests are collected in parts of 70 where continuation is supported.- The form accepts at most 200 rows per input.
maxPagesand available matches can reduce delivery. - Free Apify plan runs are capped at 200 rows across the run and 10 runs of this Actor.
- Set Maximum cost per run to cap total charges; the API setting is
maxTotalChargeUsd. - The Apify Free plan includes $5.00 in monthly usage credit (about 1,666 rows at
$0.003per row across Free-plan runs capped at 200 rows per run).
Example: a run delivering 100 rows at 1024 MB costs 100 × $0.003 + $0.005 = $0.305 on the Free plan. A run with no delivered rows has no row charges, but still incurs the start fee.
What happens when the run timeout is too short
A queued run can pause before its timeout instead of failing. It shows as ABORTED with the message "Queued on the collection backend; this run will resume automatically when results are ready (about N s)." When results are ready, the same run resumes, reports "Resumed: delivering N rows.", writes to the same dataset and finishes as SUCCEEDED if delivery succeeds.
Rows already delivered are skipped on resume, so they are not delivered or charged twice. This automatic pause can happen at most 3 times per run. Keep the default timeout of 3600 seconds to reduce pauses. A manually aborted run or a failed collection is different; automatic recovery is not promised for every stop.
The synchronous endpoints run-sync and run-sync-get-dataset-items wait at most 300 seconds and can return an empty dataset while the run is paused. For longer requests, start asynchronously and read the dataset after SUCCEEDED, or use a webhook for the succeeded event.
Use with AI agents and the API
Apify MCP server
Add this remote MCP server in Claude, ChatGPT, Cursor, VS Code or another compatible client:
https://mcp.apify.com?tools=lentic_clockss/github-scraper
Sign in with Apify through OAuth, or send Authorization: Bearer <YOUR_APIFY_TOKEN>. The tool starts a run and returns run and dataset IDs; the agent can then read rows with get-dataset-items.
Clients without remote MCP support can run npx @apify/actors-mcp-server --tools lentic_clockss/github-scraper with APIFY_TOKEN set.
Example prompt: "Find three public Python crawler repositories with GitHub Scraper and return their names, links and star counts."
- Agent execution note: Set
maxResultsbetween5and20on exploratory tool calls to keep responses compact, and readRUN_SUMMARYandINPUT_REPORTfrom the default key-value store to inspect normalized inputs and delivered row counts. When a long run briefly reportsABORTEDwith the automatic-resume status message, wait for the same run ID to finish asSUCCEEDEDinstead of starting a duplicate run.
Apify API
Python:
from apify_client import ApifyClientclient = ApifyClient("<YOUR_APIFY_TOKEN>")run = client.actor("lentic_clockss/github-scraper").call(run_input={"query": "language:python crawler", "maxResults": 3})for item in client.dataset(run["defaultDatasetId"]).iterate_items():print(item)
JavaScript:
import { ApifyClient } from 'apify-client';const client = new ApifyClient({ token: '<YOUR_APIFY_TOKEN>' });const run = await client.actor('lentic_clockss/github-scraper').call({query: 'language:python crawler', maxResults: 3});const { items } = await client.dataset(run.defaultDatasetId).listItems();console.log(items);
For asynchronous HTTP access, send the input as JSON to POST https://api.apify.com/v2/acts/lentic_clockss~github-scraper/runs, using an Authorization: Bearer <YOUR_APIFY_TOKEN> header. Read completed rows with GET https://api.apify.com/v2/datasets/<datasetId>/items?format=json.
Integrations
Use the Integrations tab to connect Google Sheets, Make, Zapier, n8n, Slack, Airtable or a webhook. Use Apify Schedules for recurring runs.
FAQ
Is it legal to scrape GitHub?
Public visibility is not permission for every use. You are responsible for GitHub's terms, applicable law and data protection requirements. Processing personal data requires a lawful basis. This is not legal advice.
Why did my run end as ABORTED?
Check the status message. The queued-run message above means automatic resume is expected. A manual abort or another failure does not mean the same thing.
How many results can I get?
Request 1–200 rows per input. The default is 70, subject to page limits, available matches and your maximum cost.
Why are some fields empty?
GitHub does not publish every field for every entity. Public emails are often absent. The Actor returns no phone numbers, street addresses or coordinates; location text is not a verified postal address.
Why do leadAbsences reasons look different from earlier runs?
From 13 November 2026, reason inside each leadAbsences object is an English code instead of a Chinese-language label; surface is unchanged. Switch filters to the new values:
Earlier reason (JSON-escaped) | Fields | New reason |
|---|---|---|
"\u8be5\u516c\u5f00\u9762\u65e0\u5b57\u6bb5" | phones, geo, address.street, address.unit, and person on organization rows | not_verified (field not on this public surface) |
"\u672c\u6837\u672c\u672a\u63d0\u4f9b" | emails when no public email was returned | not_verified (not provided in this sample) |
"request_failed" or "\u8be5\u8bf7\u6c42\u5931\u8d25" | profile, ownerProfile, and the emails, person and org a failed profile request would have filled | not_collected (profile request failed) |
"\u672a\u9a8c\u8bc1" | person when no name was returned, and org when the owner type is unknown | not_verified |
Older runs, up to about the end of October 2026, used "\u672c\u7ad9\u65e0" for phones, geo, address.street, address.unit, emails and organization-row person; these now carry the new values above.
labels: [] on an issue or pull request means it has no labels, unless quality.missingFields.labels says unavailable_in_surface (no label list was returned). Earlier runs also added a text entry under leadAbsences.labels and set quality.missingFields.labels to not_present; neither appears now, and no value says Not on source.
Do I need a GitHub personal access token?
No. Do not paste credentials into the input. Authenticated code search and private repositories are not offered through the documented inputs.
Can I collect issue bodies or repository source files?
No. Issue, pull-request and discussion rows contain metadata rather than bodies or comments. Repository mode does not clone a repository or download file contents.
Why did an organization request return no rows?
Check that org names an organization rather than a personal account, and set searchType to orgRepos. Confirm that it has public repositories matching your filter.
Why can discussion search return nothing?
A zero-row result is not proof that no discussions exist. Inspect the run message before broadening the query or changing modes.
Limitations
- Public github.com only; no GitHub Enterprise, github.co.jp, private repositories or signed-in account pages.
- Code search, Explore, Dashboard, Login, pull-request details and organization people are not available through the documented workflow.
- Search and listing coverage is bounded by
maxPages, source availability and pagination. A large limit does not guarantee a complete inventory. - Profile enrichment adds only available public details; it cannot reveal private emails.
- Duplicate entities are removed within a delivered result set. Separate runs can return the same entity again.
Related scrapers
More developer and data tools from the same publisher:
- Phone Number Validator
- Polymarket Scraper
- akamai Session solver
- AWS WAF Scraper
- Cloudflare solver
- DataDome Scraper
- Stealth Web Scraper
- Email Validator
Browse all of our scrapers at apify.com/lentic_clockss.
Support
Report a problem or request a field through the Issues tab of this Actor's page. Include the run ID and the input you used.