GitHubCard Team

This post is also available in 中文.

GitHub’s Privacy-Safe Star History API Explained

When GitHub restricted the stargazer list in July 2026 (following the June 30 announcement), a lot of Star History charts went blank overnight. Tools were not trying to collect usernames. They just had no other way to get timestamps: you paged through GET /repos/{owner}/{repo}/stargazers, kept starred_at, and threw the user object away.

On September 4, 2026, GitHub shipped the endpoint those tools actually needed: GET /repos/{owner}/{repo}/stargazers/history. It returns counts by calendar week and leaves user identities out of the response entirely.

What GET /repos/{owner}/{repo}/stargazers/history returns

Send Accept: application/vnd.github+json and X-GitHub-Api-Version: 2026-03-10. Each item in the response is one calendar week, ordered from newest to oldest:

[
  {
    "week": 1772928000,
    "total": 3,
    "days": [1, 0, 2, 0, 0, 0, 0]
  }
]

week is the Unix timestamp for the start of that week, total is the number of stars added during the week, and days gives the seven daily counts starting on Sunday. Note that the endpoint only counts existing stars—anyone who previously starred the repository and later unstarred it is not included in these buckets.

One request returns up to 30 weeks (per_page=30). Increasing page walks backward toward the week the repository was created, up to 100 pages. Weeks with zero new stars still appear in the array, so you can concatenate pages into a single timeline without guessing where the gaps are.

For public repositories, the endpoint works without authentication. A token only gives you a higher rate limit. It does not bring back the identity-level stargazer list, and it does not unlock private repositories.

Full details are in the GitHub REST API docs, the September 4 changelog, and GitHub’s engineering write-up.

Why the old endpoint was so expensive

The original stargazer list returned at most 100 people per page. Rebuilding the curve for react/react (~251,000 stars) took about 2,511 requests, and a pagination bug caused GitHub’s database to recount the repository’s stars on every page.

Simply grouping stars in SQL and paginating with LIMIT and OFFSET would not have fixed that, because the database still has to scan and group every star before it can slice out a page. GitHub’s new endpoint translates page and per_page into an indexed created_at date range first, then groups only the stars inside those weeks. For react/react, the full history drops from ~2,500 requests to 24.

Three caveats in the contract

GitHub’s engineering post is candid about what this endpoint does and does not guarantee:

  • It reflects current stars, not an event log. When someone unstars a repository, that row is gone. You get the history of people who still star the repo today.
  • Week boundaries are not guaranteed to be UTC. Treat the curve as a daily trend rather than an exact UTC audit log.
  • A viral week can still be slow. Filtering by date bounds the time range per request, not the number of stars inside a single dense week.

What we changed in GitHubCard

We switched the repository Star History widget over to the aggregate endpoint and dropped the old OAuth permission gate:

  1. Our public data route checks that the repository is public.
  2. We page through /stargazers/history, anchor the curve at the repository’s creation week, and sum the daily buckets into a cumulative series.
  3. Saving or publishing a card writes that aggregate series into the widget snapshot.
  4. Published cards render straight from the snapshot instead of calling GitHub on every view.

Concretely, the numbers on the curve are calculated from the weekly buckets in three steps:

  • Start at 0 on the creation week: Because /stargazers/history walks backward to the week the repository was created, we take the start date of that oldest week as the (date, 0) baseline point.
  • Unpack only active days: For every week bucket, we map days[0..6] (Sunday through Saturday) to calendar dates and keep only the days where count > 0, so quiet periods do not bloat the series with flat duplicate points.
  • Running cumulative sum: We sort those active days chronologically and keep a running total (value += count). Each point (date, value) on the chart is the cumulative number of current stars up through that day, and the final point equals the sum of all weekly total values.

You can now add or refresh Star History for any public repository as a guest. We no longer ask for GitHub sign-in or the public_repo scope just to draw the chart. If you are repairing an older card, see Blank Star History Chart? Fix Your Repo or go straight to the repository card editor. For embed formats after you publish, see How to Embed a GitHub Repository on Any Website.

FAQ

Do I still need to sign in or grant public_repo to add Star History?

No. Public repositories expose aggregate star history without authentication, so you can add or refresh the Star History widget in GitHubCard as a guest. Sign-in is only required when you want to save or publish a design to your account.

Does the new Star History API expose who starred my repository?

No. GET /repos/{owner}/{repo}/stargazers/history returns only weekly totals and seven daily counts per week. Usernames, user IDs, and avatars are not part of the response.

Why is my older Star History embed still blank?

Cards published during the July–August 2026 restriction window may have been saved without a snapshot. Open the repository in the repository card editor, refresh the Star History widget, and republish the card to update the embed.


GitHubCard Team

Turn this into a card

Turn the ideas from this article into an editable GitHub profile card, repo card, or README section.