A production-ready, self-hosted API that generates dynamic SVG cards and JSON summaries for any GitHub profile — stats, top languages, contribution streaks, and pinned-repo cards. Built as Vercel serverless functions in TypeScript, using only the GitHub GraphQL + REST APIs (no third-party data broker, no scraping).
/api/stats— stars, commits (full account history, not just this year), PRs, issues, code reviews, and a computed percentile rank (S, A+, A, A-, B+, ...), rendered as an animated SVG card with a progress ring./api/top-langs— aggregated language breakdown across all owned, non-fork repos, withnormalandcompactlayouts./api/streak— total contributions, current streak, and longest streak computed from the account's entire contribution history (not limited to the last year like the GitHub UI)./api/pin— a single repository card, similar to GitHub's own pinned-repositories widget./api/profile— all of the above as plain JSON, for building your own UI, Discord bot, CLI, etc.- 9 built-in themes (
dark,radical,dracula,tokyonight,gruvbox,merko,github_dark,ocean,default) plus per-card hex color overrides. - Multi-token rotation & rate-limit failover — configure one or several
GITHUB_TOKENs and requests automatically round-robin and fail over if one token is rate-limited. - Smart HTTP caching —
Cache-Control+stale-while-revalidateheaders tuned for CDN/edge caching, with a per-requestcache_secondsoverride. Error cards are always servedno-storeso a transient failure self-heals immediately once retried. - Graceful failure — bad usernames, missing repos, and upstream GitHub errors render as a readable SVG error card instead of a broken image or a raw stack trace.
- Zero required runtime dependencies (uses the Node 18+ global
fetch).
Create a fine-grained personal access token with read-only access to public repositories (no special scopes needed for public data). Classic tokens work too — no scopes required for public data.
- Push this folder to a new GitHub repository.
- Go to vercel.com/new and import that repository.
- Under Environment Variables, add:
GITHUB_TOKEN— your token (comma-separate multiple tokens to raise your effective rate limit, e.g.ghp_aaa,ghp_bbb)CACHE_SECONDS— optional, default1800
- Deploy. Vercel auto-detects the
api/*.tsfiles as serverless functions — no build step is required.
npm install -g vercel
npm install
vercel devThen open http://localhost:3000 for interactive docs and examples.
| Param | Default | Description |
|---|---|---|
username |
— | Required. GitHub login. |
theme |
default |
Preset theme name. |
hide |
— | Comma list to hide rows: stars,commits,prs,issues,reviews,contribs |
show_icons |
true |
Show unicode icons next to each stat. |
hide_rank |
false |
Hide the percentile rank ring. |
hide_border |
false |
Hide the card border. |
include_all_commits |
true |
Count commits across all years vs. capping at 1000 for rank scoring. |
card_width |
495 |
Card width in px. |
custom_title |
— | Override the card heading. |
cache_seconds |
1800 |
Clamped to 300–86400. |
title_color, text_color, icon_color, bg_color, border_color, ring_color |
theme default | Hex overrides (no #). |
| Param | Default | Description |
|---|---|---|
username |
— | Required. |
layout |
normal |
normal or compact. |
langs_count |
8 |
1–20 languages shown. |
exclude_repo |
— | Comma list of repo names to exclude. |
exclude_langs |
— | Comma list of language names to exclude. |
theme, card_width, custom_title, cache_seconds, color overrides |
— | Same as /api/stats. |
| Param | Default | Description |
|---|---|---|
username |
— | Required. |
theme, color overrides, cache_seconds |
— | Same as above. |
| Param | Default | Description |
|---|---|---|
username |
— | Required. Repo owner. |
repo |
— | Required. Repo name. |
theme, color overrides, cache_seconds |
— | Same as above. |
Returns JSON:
{
"username": "octocat",
"name": "The Octocat",
"rank": { "level": "A+", "percentile": 8.42 },
"stats": { "totalStars": 123, "totalCommits": 456, "totalPRs": 12, "totalIssues": 34, "totalReviews": 5, "followers": 999, "contributedTo": 20 },
"topLanguages": [{ "name": "TypeScript", "color": "#3178c6", "percentage": 41.2 }],
"streak": { "totalContributions": 3210, "currentStreak": 4, "longestStreak": 57, "firstContribution": "2019-02-14" },
"generatedAt": "2026-08-07T12:00:00.000Z"
}- Data source: GitHub GraphQL API for user/repo/contribution data, GitHub REST Search API for PR/issue/review counts (the GraphQL schema doesn't expose account-wide PR/issue totals directly).
- Multi-year aggregation: GitHub's
contributionsCollectiononly covers one year per call, so/api/statsand/api/streakalias one call per calendar year of the account's life inside a single GraphQL request. - Rank formula: a weighted percentile score across commits, PRs, issues,
reviews, stars, and followers using exponential/log-normal CDFs, mapped to
letter grades S through C — the same general approach popularized by the
open-source
github-readme-statsproject, reimplemented here. - Rate limits: an unauthenticated GitHub REST/GraphQL call is capped at
60 req/hr; an authenticated token gets 5,000 req/hr (GraphQL cost-based).
Configure multiple comma-separated tokens in
GITHUB_TOKENto multiply your effective ceiling — the client round-robins per request and retries the next token if one comes back rate-limited or unauthorized.
MIT — do whatever you like with it.