BYTETOOLS

GitHub Contributions Chart API

Fetch any public GitHub user's contribution graph as JSON: per-day counts, colours and yearly totals. No token needed. Live example and the CORS caveat.

No API key requiredHTTPSFree tier

Endpoint tested and returned HTTP 200 on 2026-08-21

What is the GitHub Contributions Chart API?

The GitHub Contributions API returns a public user's contribution graph as structured JSON. `GET https://github-contributions.vercel.app/api/v1/{username}` gives yearly totals plus a per-day array of dates, counts, colours and intensity levels, with no GitHub token required.

GitHub's own REST API has never exposed the contribution graph; you can get it from GraphQL, but only with an authenticated token, which rules it out for a static site or a public widget. This service scrapes the rendered graph and republishes it as JSON, which is why it needs no credentials at all. That is its entire reason to exist, and it is a good one.

The shape has two quirks worth planning for. `contributions` covers whole calendar years, so the current year includes future dates with a count of zero, and the array is ordered newest first. `year` and `intensity` arrive as strings while `count` and `total` are numbers, so sorting or comparing without casting will produce lexicographic nonsense. The endpoint also sends no CORS header, so despite being perfect for a browser widget it has to be fetched server-side or at build time.

Quick facts

Base URL
https://github-contributions.vercel.app/api/v1
Authentication
No GitHub token and no account. Only public contribution data is available, which is exactly what the profile page shows.
Rate limit
Not published. It runs on a shared serverless deployment, so cache results for at least a day.
Pricing
Free and open source.
CORS
Not enabled — call it from your server
Official docs
Read the docs

How to use the GitHub Contributions Chart API

Every request below was executed against the live API on 2026-08-21, and the response shown is the real body it returned — not an illustration.

1. Fetch a user's full contribution history

GET https://github-contributions.vercel.app/api/v1/anuraghazra

curl
curl 'https://github-contributions.vercel.app/api/v1/anuraghazra'
JavaScript (fetch)
const res = await fetch("https://github-contributions.vercel.app/api/v1/anuraghazra");
if (!res.ok) throw new Error(`Request failed: ${res.status}`);
const data = await res.json();
console.log(data);
Python (requests)
import requests

res = requests.get("https://github-contributions.vercel.app/api/v1/anuraghazra", timeout=20)
res.raise_for_status()
print(res.json())
Response — HTTP 200 (truncated)
{
  "years": [
    {
      "year": "2026",
      "total": 258,
      "range": {
        "start": "2026-01-04",
        "end": "2026-12-26"
      }
    },
    {
      "year": "2025",
      "total": 367,
      "range": {
        "start": "2025-01-05",
        "end": "2025-12-27"
      }
    },
    {
      "year": "2024",
      "total": 497,
      "range": {
        "start": "2024-01-07",
        "end": "2024-12-28"
      }
    },
    {
      "year": "2023",
      "total": 784,
      "range": {
        "start": "2023-01-01",
        "end": "2023-12-30"
      }
    },
    {
      "year": "2022",
      "total": 680,
      "range": {
        "start": "2022-01-02",
        "end": "2022-12-31"
      }
    },
    {
      "year": "2021",
      "total": 811,
      "range": {
        "start": "2021-01-03",
        "end": "2021-12-25"
      }
    },
    {
      "year": "2020",
      "total": 1555,
      "range": {
        "start": "2020-01-05",
        "end": "2020-12-26"
      }
    },
    {
      "year": "2019",
      "total": 1062,
      "range": {
        "start": "2019-01-06",
        "end": "2019-12-28"
      }
    },
    {
      "year": "2018",
      "total": 368,
      "range": {
        "start": "2018-01-07",
        "end": "2018-12-29"
      }
    }
  ],
  "contributions": [
    {
      "date": "2026-12-31",
      "count": 0,
      "color": "#ebedf0",
      "intensity": "0"
    },
    {
      "date": "2026-12-30",
      "count": 0,
      "color": "#ebedf0",
      "intensity": "0"
    },
    {
      "date": "2026-12-29",
      "count": 0,
      "color": "#ebedf0",
      "intens

Parameters

ParameterTypeRequiredDescription
{username}pathRequiredAny public GitHub username. anuraghazra
ystringOptionalRestrict the response to one year, or pass `last` for the trailing twelve months. 2023
formatstringOptionalAlternative output formats offered by the project, including nested structures keyed by year. nested

Response fields

yearsarray
One entry per year with data, newest first. Each has `year`, `total` and a `range` of the first and last day counted.
years[].yearstring
The year as a string, not a number. Cast before comparing or sorting.
years[].totalinteger
Total contributions that year. This is the number GitHub shows above the graph.
years[].rangeobject
`start` and `end` dates as ISO strings. They are graph week boundaries, so `start` is usually not 1 January.
contributionsarray
Every day across all years, newest first. Includes future days of the current year with a count of zero.
contributions[].countinteger
Contributions on that day. Zero is common and meaningful; do not filter it out when drawing a heatmap.
contributions[].colorstring
The hex swatch GitHub would render, such as `#ebedf0` for an empty day.
contributions[].intensitystring
Bucket level `0` to `4`, as a string. Use it if you want GitHub's own scale rather than deriving your own from counts.

What you can build with the GitHub Contributions Chart API

  • Render a contribution heatmap on a personal site without a GitHub token
  • Build a yearly wrap-up or streak tracker from real commit activity
  • Feed contribution data into a dashboard alongside other developer metrics
  • Generate an image or PDF summary of a year's open source activity
  • Compare activity between team members on public repositories

Common errors and how to fix them

404

The username does not exist or the profile is not public.

Fix: Check the spelling on github.com first; the API mirrors whatever the public profile page shows.

CORS error in the browser

No `Access-Control-Allow-Origin` header is returned.

Fix: Fetch server-side, or during a static build, and serve the JSON from your own origin.

Empty or partial years

GitHub only renders contributions from the account's creation year onwards, and private contributions are excluded unless the user opted to show them.

Fix: Treat gaps as real data rather than as an error.

GitHub Contributions Chart API — frequently asked questions

Do I need a GitHub token for this API?

No. That is the whole point: GitHub's own GraphQL API requires authentication for contribution data, while this service republishes the public graph without credentials.

Does it include private contributions?

Only if the user has enabled 'Include private contributions on my profile'. Otherwise the counts reflect public activity alone, exactly as the profile page does.

Why does the current year include future dates?

The contribution graph is drawn for whole calendar years, so the array runs to 31 December with zero counts for days that have not happened yet. Filter by today's date if that matters.

Can I call it from a browser widget?

Not directly, because there is no CORS header. Fetch it at build time or through your own small proxy endpoint.

Tools that pair with this API

GitHub Contributions Chart is an independent third-party service and is not affiliated with ByteTools or ByteVancer. Details on this page were verified on 2026-08-21; always check the official documentation before relying on this API in production, as terms and limits can change.