Skip to main content
Endpoint: GET /api/wrapped
Generate comprehensive year-in-review analytics for any GitHub repository, including contribution statistics, language breakdown, release history, and community growth metrics.

Request

Query Parameters

owner
string
required
Repository owner (username or organization name)Example: vercel, facebook, torvalds
repo
string
required
Repository nameExample: next.js, react, linux
year
number
default:"Previous year"
Year to generate wrapped for (2008 - current year)Example: 2024
accessToken
string
GitHub personal access token for private repositoriesNote: When provided, caching is disabled to protect private data.

Validation Rules

  • owner: Must be at least 1 character
  • repo: Must be at least 1 character
  • year: Integer between 2008 and current year
  • accessToken: Optional, required for private repositories

Response

Success Response

data
WrappedData
The complete wrapped analytics data
cached
boolean
Whether this response was served from cache

Error Responses

{
  "error": "Invalid parameters",
  "details": [
    {
      "code": "too_small",
      "minimum": 2008,
      "type": "number",
      "path": ["year"],
      "message": "Number must be greater than or equal to 2008"
    }
  ]
}

Examples

Basic Request

curl "https://your-domain.com/api/wrapped?owner=vercel&repo=next.js&year=2024"

Private Repository Request

curl "https://your-domain.com/api/wrapped?owner=myorg&repo=private-repo&year=2024&accessToken=ghp_xxxxx"

Example Response

{
  "data": {
    "repository": {
      "owner": "vercel",
      "repo": "next.js",
      "name": "vercel/next.js",
      "description": "The React Framework",
      "stars": 125000,
      "forks": 26800,
      "language": "TypeScript"
    },
    "year": 2024,
    "contributors": {
      "topByCommits": [
        {
          "login": "timneutkens",
          "avatar_url": "https://avatars.githubusercontent.com/u/6324199",
          "contributions": 342,
          "linesAdded": 12500,
          "linesRemoved": 8300
        }
      ],
      "topByLines": [...],
      "newContributors": 156,
      "total": 2847
    },
    "activity": {
      "total": 3842,
      "byMonth": {
        "Jan": 285,
        "Feb": 312,
        "Mar": 398
      },
      "byDayOfWeek": {
        "Monday": 612,
        "Tuesday": 589
      },
      "byHour": {
        "0": 45,
        "1": 32
      },
      "busiestMonth": { "month": "Mar", "count": 398 },
      "busiestWeek": { "week": "2024-W12", "count": 156 },
      "averagePerDay": 10.5
    },
    "community": {
      "starsGained": 15000,
      "forksGained": 2100,
      "issuesOpened": 1850,
      "issuesClosed": 1720,
      "prsMerged": 1245,
      "watchersGained": 450
    },
    "languages": [
      {
        "language": "TypeScript",
        "bytes": 8500000,
        "percentage": 78.5
      },
      {
        "language": "JavaScript",
        "bytes": 1200000,
        "percentage": 11.2
      }
    ],
    "releases": [
      {
        "tag_name": "v14.0.0",
        "published_at": "2024-05-15T10:30:00Z",
        "name": "Next.js 14",
        "isMajor": true
      }
    ],
    "mostEditedFiles": [
      { "path": "packages/next/src/server/base-server.ts", "changes": 156 },
      { "path": "packages/next/src/client/index.tsx", "changes": 142 }
    ],
    "generatedAt": "2026-03-03T08:00:00Z"
  },
  "cached": false
}

Rate Limiting

The endpoint checks GitHub API rate limits before processing:
  • Requires at least 10 remaining requests to proceed
  • Returns 429 status if rate limit is too low
  • Authenticated requests have higher limits (5,000/hour vs 60/hour)

Caching Behavior

  • Public repository data is cached for 24 hours
  • Private repository data is never cached
  • Requests with accessToken parameter bypass cache
  • Cache key format: wrapped:{owner}:{repo}:{year}

Source Code

Implementation: app/api/wrapped/route.ts

User Wrapped

Generate user activity analytics

Validate Repository

Validate repository exists before generating wrapped

Build docs developers (and LLMs) love