Refolk
TeardownSales and go-to-market

From Repo Stargazers to a Qualified Meeting List

You can take one repo, pull and filter its stargazers, recover emails, drop bots and stale signals, and finish with a ranked meeting list and a predicted yield at each stage.

15 min readLast reviewed August 16, 2026Read as Markdown

This guide takes one open-source repository and carries it end to end: from raw stargazers to a short, deduplicated, ranked list of people worth booking a meeting with. It is for founders selling their own dev tool, AEs and SDR leads running developer-led sales, and partnerships teams who want to know the yield before they run the pull. You will see the real endpoints, the drop-off at each stage, and the wrong turns that quietly cost you most of your list.

The working example is a Kubernetes-adjacent tool selling to platform and backend engineers. I will use a 10,000-star repo as the illustrative top of funnel. Every stage count below is a derived estimate built from cited rates, not a measured number, and you should recount your own drop-off on the first run.

What "turn GitHub stargazers into leads" actually means

Stargazer mining means taking the accounts that starred a repo, treating the star as a buying signal, and converting those accounts into deliverable, deduplicated contacts you can route to sales. The job is not "get a list of usernames." It is "get a short list of real buyers, with emails, ranked, minus your existing customers."

A star is a weak-but-real intent signal: someone found your category interesting enough to bookmark it. That signal decays fast and it is polluted by bots, so most of the work is subtraction. You start wide and narrow hard. The value is in knowing exactly where the funnel collapses so you can predict your own before you spend a week on it.

~15%
Share of GitHub users who expose a public email on their profile
The profile email field is null for the vast majority of accounts, so most of your recovery work happens after the profile fetch.

The funnel: where a 10,000-star pull actually lands

Expect the deliverable list to be under a quarter of raw stars. Two forces do the damage: recency-and-bot filtering removes roughly 44% of the top, and the email cliff removes most of what remains because profile email is private by default.

Here is the yield model for the worked example. Treat these as derived estimates.

StageRetainedBasis
Raw stargazers10,000Repo star count (illustrative)
After recency + bot drop~5,600Fake-star prevalence plus recency loss
Emails recovered~1,700 to 2,20030 to 40% commit recovery on active accounts
Replies at signal band~255 to 55015 to 25% signal reply rate

The shape matters more than the exact numbers. The biggest single drop is the email cliff between the human-developer list and the recovered-email list, because only about 15% of users expose a profile email and commit recovery adds back only 30 to 40% of active accounts.

Stargazer funnel for one 10,000-star repo

  1. Raw stargazers
    10,000

    repo star count

  2. After recency + bot drop
    5,600

    derived from prevalence and staleness

  3. Emails recovered
    2,000

    30 to 40% commit recovery

  4. Replies at signal band
    400

    15 to 25% signal reply rate

The deliverable list is often under a quarter of raw stars, and the steepest drop is email recovery, not the rate limit.

The API path: endpoints, pagination, and the timestamp you must not skip

Pull stargazers from the starring endpoint, page at 100 per request, and send the application/vnd.github.star+json Accept header so each row carries a starred_at timestamp. Without that header the timestamp is silently dropped and you cannot filter by recency.

The mechanics, in order:

  • Authenticate. The authenticated REST limit is 5,000 requests per hour. Unauthenticated is 60 per hour, which is unusable for anything past a toy repo. A GitHub App owned by an Enterprise Cloud org gets 15,000 per hour.
  • Paginate the stargazers list. The endpoint pages at per_page max 100, default 30, with a page parameter starting at 1. A 10,000-star repo is 100 list calls at 100 per page.
  • Capture starred_at. Send the star+json media type or you lose the one field that lets you filter stale stars.
  • Fetch each profile. Call the users endpoint once per login for name, company, location, bio, and email. This is where the bulk of your calls go.
  • Use conditional requests. A conditional request that returns a 304 does not count against your primary rate limit if it was made while correctly authorized, which helps on re-runs.

That comes out to roughly 4 to 5 API calls per lead: list, profile, an events or commit scan for email, and a CRM dedupe check. At 5,000 per hour, a 10,000-star repo is genuinely hours of work, so scope the pull before you start.

The step-by-step procedure

Work the repo in this order. Each step has a clear "done" condition so you know when to move on.

One repo, end to end

  1. Pick and vet the repo
    Select one repo whose stargazers match your ICP, then run a fake-star check before anything else. Done = repo confirmed organic and star count noted as your funnel top.
  2. Pull stargazers with timestamps
    Paginate the stargazers endpoint at per_page=100 using the star+json media type so each row carries starred_at. Done = full CSV of logins plus star dates.
  3. Filter by recency
    Drop stars older than the 3 to 6 month window, since older stars rarely convert. Done = only fresh signals remain.
  4. Drop bots and low-signal accounts
    Remove [bot] logins, same-week-created zero-repo zero-follower accounts, and coordinated clusters. Done = human-developer list.
  5. Fetch user profiles
    Call the users endpoint once per login for name, company, location, bio, and public email. Done = enriched rows, most with null email.
  6. Recover emails from commits
    For null-email rows, scan public events and recent commit patches for author emails, discarding any noreply address. Done = deliverable emails attached.
  7. Enrich employer and dedupe against CRM
    Add company and seniority, then remove existing customers and open contacts. Done = deduplicated, net-new list.
  8. Score and rank
    Flag maintainers and power users, then rank by ICP fit and seniority. Done = ranked meeting list with expected yield per stage.

On recency: why 3 to 6 months, and where sources disagree

Stars older than 3 to 6 months rarely convert because developers move on and the interest goes cold. The core problem with cold developer lists is timing: they are compiled weeks or months before contact. Recency filtering fixes both the intent and the deliverability problem at once, because someone who starred a year ago is likelier to have changed jobs, which means a bounced email.

Sources disagree here. Some tools push every historical star to maximize list size. Practitioners cap at 3 to 6 months. I side with the cap: a stale star is a worse signal and a worse address. If you must go wider, segment the old stars into their own low-priority campaign rather than mixing them into your fresh list.

On email recovery: the method and the ceiling

For rows where the profile email is null, append .patch to a commit URL or query the public events feed, which sometimes exposes commit author email even when the profile email is hidden. Recovery runs about 30 to 40% of developers who have public repo activity. The hard ceiling: many developers switched to id+username@users.noreply.github.com commit emails after GitHub made that the default in 2017. If you see that pattern, the real email is masked and the address is undeliverable. Regex it out.

Reading the list: who a stargazer actually is

Most stargazers are individual contributors, not budget holders, so seniority enrichment is where the leverage lives. If you route every recovered email to an AE, you burn most of the list on people who cannot buy.

In Refolk's index, the split for one stack looks like this.

BandCountShare of pooled total
Senior IC49,87687.1%
Director / VP / CXO7,39912.9%

Both counts come from Refolk's index for Kubernetes-skilled people in the United States; shares are derived from a pooled total of 57,275. The read: a stargazer list skews roughly 6.7 senior ICs per senior decision-maker. That does not make the ICs worthless. It means you route them to a product-led or community motion and reserve AE time for the 12.9% and the maintainers.

12.9%
Share of Kubernetes-skilled senior-and-above people who are director level or above
From Refolk's index. Enrich seniority before routing, or you spend AE hours on people who cannot sign.

Geography changes the volume you are working with. The same title returns very different pool sizes by country.

CountryCountUS multiple
United States49,8761.0x
Germany9,2225.4x smaller

Both counts are from Refolk's index for senior Kubernetes engineers; the multiple is derived. A US repo yields more raw volume, but a German segment may face less inbox saturation, so it can be worth splitting sends by region rather than blasting one template into the largest pool.

Rebuilding this seniority-and-geography read by hand means enriching thousands of logins one at a time. Asking for the population directly is the shortcut.

That is the one place Refolk collapses the most tedious part of this playbook: instead of pulling every login and running the email cliff yourself, you ask for the segment that already survives it.

How this goes wrong: the failure modes that eat your list

Most stargazer pipelines fail silently. They produce a list that looks finished but is 15% populated, salted with bots, and benchmarked against the wrong number. Here are the specific ways it breaks and how to catch each one.

  • Ignoring starred_at. Without the star+json media type there is no timestamp, so you cannot filter by recency and end up mailing 12-month-old stars. Check: confirm every row has a timestamp before you filter.
  • Trusting the profile email field. It is null roughly 85% of the time, so a pipeline that stops at the profile silently loses most of the list. The false positive is a "complete" export that is only 15% populated. Check: count non-null emails as a share of rows.
  • Accepting noreply addresses. id+login@users.noreply.github.com is masked and undeliverable. The false positive is an "email found" flag on a masked address. Check: regex-drop anything containing noreply.
  • Fake-star contamination. Buying or mining a stargazer list during a 16.66%-prevalence era means mailing bot accounts. Check: run a fake-star audit and inspect account-age and same-week-creation clusters.
  • Over-trusting visual bot checks. Aged premium bot accounts look human, with bios and green squares. The false positive is "verified real" because the profile looks lived-in. Check: cluster on shared activity dates and shared target repos, not appearance.
  • Mistaking a star for a buyer. Most stargazers are ICs, not budget holders. Check: enrich seniority before routing to AEs.
  • Benchmarking against the 3.43% average. A star is a buying signal, so the 15 to 25% band applies. Using the 3% average makes a healthy funnel look broken. Check: segment reply rate by whether the copy references the star.

The fake-star base rate is not what it used to be

Before 2022, fake stars on 50+ star repos were near zero. By mid-2024, 16.66% of such repos were in fake-star campaigns. One study identified roughly 6 million fake stars across 18,617 repos by about 301,000 accounts, and by January 2025, 90.42% of the flagged repos and 57.07% of the flagged accounts had been deleted. The deletion rate is why you audit at pull time rather than trusting a list someone compiled earlier: the accounts you mail may already be gone.

Route by seniority and email deliverability

Decision-maker or maintainerIndividual contributor
IC, no email
Skip for direct mail; capture for community or product-led motion
IC, deliverable
Nurture sequence, self-serve or PLG path, not AE time
Decision-maker, no email
Find another channel; worth manual research
Decision-maker, deliverable
AE queue, top priority, reference the repo in the first line
Email masked or missingDeliverable email
Two variables decide whether a recovered stargazer belongs in an AE queue, a nurture, or the discard pile.

Why the star framing changes everything

Frame the outreach around the star and you move from the 3.43% cold average into the 15 to 25% signal band, a roughly 5x lift. The star is the signal. A mail that names the repo captures that lift; a generic mail throws it away.

The benchmarks stack in your favor if you respect them:

  • Generic cold email now averages a 3.43% reply rate, down from 5.1%.
  • Outreach referencing a specific buying signal, such as a repo star, hits 15 to 25%.
  • Small sends win: campaigns under 50 recipients average 5.8% reply versus 2.1% for large blasts.
  • Verified lists reply at roughly 2x the rate of unverified.
  • Meeting-booking runs around 1% of cold sends as a baseline, which the signal framing lifts.

So the shape of the send matters as much as the list. Keep segments under 50, verify addresses, and open with the repo. Here is a first-touch skeleton that does that.

First-touch email for a recovered stargazer
Subject: you starred {repo}

Hi {first name},

I noticed you starred {repo} a few weeks back, so you are probably wrestling with {category problem} on {their stack}.

I build {your tool}, which handles {the specific thing} without {the usual pain}. Teams using {competing approach} tend to switch when {trigger}.

Worth 15 minutes to see if it fits how you run {their environment}? I can work around your week.

{your name}

Replace the repo and category with your own; keep the send under 50 recipients per segment and never send to a noreply address.

The star is the signal, so a mail that names the repo captures a 5x lift while a generic mail throws it away.

Before you call the list done

Run this checklist against the finished list. Every item is a specific thing to verify, not a topic to think about.

Meeting-list readiness

  • Every row carries a starred_at timestamp and all stars fall inside the 3 to 6 month window.
  • A fake-star audit was run on the repo and same-week-creation clusters were removed.
  • All [bot] logins and zero-repo zero-follower same-week accounts are gone.
  • Non-null emails are counted as a share of rows and the number is recorded, not assumed.
  • Every address containing noreply has been dropped.
  • Seniority is enriched, and ICs are routed away from the AE queue.
  • The list is deduplicated against the CRM with existing customers and open contacts removed.
  • Maintainers and power users are flagged and ranked to the top.
  • Reply rate will be measured against the 15 to 25% signal band, segmented by whether copy references the star.

Keeping the pull current

A stargazer list is perishable. Stars go stale inside 3 to 6 months, people change jobs, and flagged bot accounts get deleted, so a list you sat on for a quarter is worth re-pulling rather than re-sending. The right cadence is to re-run the pull on a rolling window and mail only the fresh cohort each time, treating the repo as a stream, not a one-off export.

Re-check three mechanisms rather than memorizing their current values. First, the fake-star prevalence rate, which climbed from near zero to 16.66% and will keep moving; audit every pull. Second, the cold reply average, which fell from 5.1% to 3.43% and sets the baseline your signal band is measured against. Third, GitHub's email defaults, which have already flipped once toward privacy and drive your recovery ceiling. When any of these shifts, your funnel model shifts with it, so recount your own drop-off each time rather than trusting the numbers from a prior run.

The discipline that survives all of this is the same one: start wide, subtract hard, enrich seniority before you route, and frame every send around the star that put the person on your list in the first place.

Questions practitioners ask

How many leads can I expect from a 10,000-star repo?

Plan for under a quarter of raw stars as deliverable contacts. After recency filtering and bot removal you keep roughly 5,600, and commit-based email recovery returns emails for about 30 to 40% of active accounts, leaving around 1,700 to 2,200 deliverable rows. At a 15 to 25% signal reply rate that is roughly 255 to 550 replies. Treat all of these as derived estimates, not measured counts, and recount your own drop-off on the first run.

Why is the email field null for most GitHub users?

GitHub flipped profile email to private by default years ago, so the users endpoint returns null for the vast majority of accounts, and only about 15% expose a public profile email. To recover the rest you scan public commit metadata, appending .patch to commit URLs or reading the public events feed, which yields real emails for 30 to 40% of active developers. Discard any id+login@users.noreply.github.com address; it is masked and undeliverable.

How do I know if a repo's stars are fake?

Run a fake-star audit before you invest in a pull. Coordinated fake accounts share a fingerprint: created the same week, no bio, no followers, no original repos, and starring the same handful of repos inside a two-hour window. Cluster on shared activity dates and shared target repos rather than on how a single profile looks, because aged premium bot accounts pass a visual check. By mid-2024, 16.66% of repos with 50+ stars were in campaigns.

What reply rate should I benchmark against?

Use the 15 to 25% signal band, not the 3.43% cold average. A repo star is a specific buying signal, so outreach that names the repo sits in the same band as outreach referencing funding rounds or leadership changes, which is roughly a 5x lift over generic cold email. Small, targeted sends help too: campaigns under 50 recipients average 5.8% reply versus 2.1% for large blasts.

Should I mail every stargazer I recover?

No. Most stargazers are individual contributors, not budget holders. In Refolk's index only 12.9% of Kubernetes-skilled senior-and-above people are director level or above, so routing every recovered email to an AE wastes most of the list. Enrich seniority first, route ICs to product-led or community motions, and reserve AE time for the decision-makers and maintainers.

Try it on your own search

Stop building boolean strings. Just describe the person.

Type one sentence and I plan the search, read GitHub, public LinkedIn and Crunchbase records, and the open web live, then hand back a ranked shortlist with the reasoning behind every name. No filters to learn, no export to clean up, no sales call to sit through.

  • One sentence in, a ranked shortlist out. No boolean, no filters, no seat to buy.
  • Read live at search time, not from a database that went stale last quarter.
  • Watch every step as it runs, and see why each name made the list.

500 free credits on sign-up. No card, no demo call. See real searches.

Read next