Back to blog
GitHub APIGitHub followerscontribution graph

GitHub followers API — and the contribution graph REST will not give you

CaptapiOctober 10, 20263 min read
TL;DR
Public followers are a thin wrap of GitHub REST. The calendar and github.com/trending are the surfaces REST does not ship as JSON.
GitHub followers API — and the contribution graph REST will not give you

GitHub's public REST already lists followers at GET /users/{login}/followers. GET /v1/github/followers is the same cards behind one Captapi key (~0.1 credits per row, minimum 3). The reason to call it here is not "GitHub requires OAuth for public profiles" — it doesn't. The reason is the two surfaces GitHub's REST does not give you as JSON: the contribution calendar and github.com/trending.

Numbers below are from production on October 10, 2026.

Followers are a thin card

torvalds, limit=5:

{
  "username": "torvalds",
  "totalReturned": 5,
  "hasMore": true,
  "nextCursor": "eyJ2IjoxLCJrIjoiZm9sbG93ZXJzIiwicCI6Mn0",
  "followers": [
    {
      "id": 206,
      "login": "sprsquish",
      "type": "User",
      "url": "https://github.com/sprsquish",
      "avatar": "https://avatars.githubusercontent.com/u/206?v=4"
    }
  ]
}

Each row is {id, login, type, url, avatar}. type is User or Organization. nextCursor is GitHub's Link header, opaque — not a page number. The same shape is /v1/github/following.

Linus's profile on the same session reported followers: 327047. There is no since / sample parameter. Exhausting that list at 0.1 credits/row is tens of thousands of credits. For a full archive, call api.github.com with your own token. Use this endpoint when you already want one key across platforms and a short page.

The call

JavaScript:

const headers = { Authorization: `Bearer ${process.env.CAPTAPI_KEY}` };
const qs = (p) => new URLSearchParams(p);

const follows = await fetch(
  "https://api.captapi.com/v1/github/followers?" + qs({ username: "torvalds", limit: "5" }),
  { headers },
).then((r) => r.json());

const graph = await fetch(
  "https://api.captapi.com/v1/github/contributions?" + qs({ username: "torvalds" }),
  { headers },
).then((r) => r.json());
console.log(graph.data.totalContributions, graph.data.currentStreak);

Python:

import httpx, os
h = {"Authorization": f"Bearer {os.environ['CAPTAPI_KEY']}"}

follows = httpx.get(
    "https://api.captapi.com/v1/github/followers",
    params={"username": "torvalds", "limit": 5},
    headers=h, timeout=30,
).json()["data"]

graph = httpx.get(
    "https://api.captapi.com/v1/github/contributions",
    params={"username": "torvalds"},
    headers=h, timeout=30,
).json()["data"]
print(graph["totalContributions"], graph["currentStreak"], graph["from"], graph["to"])
print(graph["days"][0])  # {date, count, level}

The trap: events ≠ the contribution graph

/users/{u}/events/public caps at about 90 events / 90 days. That is /v1/github/activity, and it is not a heatmap. /v1/github/contributions scrapes github.com/users/{login}/contributions (the response stamps source with that URL) and returned, for torvalds:

{
  "totalContributions": 3805,
  "from": "2025-10-05",
  "to": "2026-10-10",
  "currentStreak": 103,
  "longestStreak": 103,
  "days": [
    { "date": "2025-10-05", "count": 10, "level": 1 },
    { "date": "2025-10-07", "count": 13, "level": 2 }
  ]
}

371 day rows, sorted ascending by date — not GitHub's weekday-major DOM order. currentStreak uses GitHub's today-grace rule: a zero on today does not break the streak; a zero on any earlier day does. Flat 2 credits.

The other REST-shaped miss is "trending." Sorting /search/repositories by stars is all-time stars. /v1/github/trending-repositories?since=weekly&language=python scrapes github.com/trending and ranked earthtojake/text-to-cad first that week: stars: 18885, starsGained: 2125, since: "weekly". No cursor; the HTML page listed 12 rows. Flat 2 credits.

A single repo is /v1/github/repository (1 credit). vercel/next.js that day: stars: 143101, watchers: 1631. watchers is GitHub's subscribers_count (people notified of activity), not the legacy watchers_count star alias. List payloads on /repositories omit watchers and parent — call repository when you need them.

Honesty on the wrap: /v1/github/user and the follower/repo lists are camelCase over GitHub's free public REST (60 req/hour unauthenticated on GitHub's side; Captapi is the meter you hit). Call api.github.com directly for GitHub-only jobs. Come here for the calendar, trending, and a single key next to Instagram and TikTok.

The followers page and the contributions page have the envelopes. A free key is 100 credits — a contributions call plus a followers page and a trending snapshot.