Skip to main content
Endpoint: GET /api/summaryAuthentication Required
Retrieve a monthly activity summary for the currently authenticated user. This endpoint generates a focused snapshot of GitHub activity for a specific month and year.

Authentication

This endpoint requires authentication. Users must be logged in via GitHub OAuth.
The endpoint:
  1. Validates the user has an active session
  2. Retrieves the GitHub access token from the session
  3. Fetches the authenticated user’s GitHub profile
  4. Generates a monthly wrapped summary

Request

Query Parameters

year
number
default:"Current year"
Year to generate summary for (2008 - current year)Example: 2024
month
number
default:"Current month"
Month to generate summary for (1-12)Example: 3 (March)
accessToken
string
Optional GitHub personal access token overrideNote: Typically not needed as the session token is used automatically.

Validation Rules

  • year: Integer between 2008 and current year
  • month: Integer between 1 and 12

Response

data
UserWrappedData
User wrapped data scoped to the specified monthThe structure is similar to /api/wrapped/user but focused on a single month’s activity.See User Wrapped for the full data structure.

Examples

Specific Month Request

curl "https://your-domain.com/api/summary?year=2024&month=3" \
  -H "Cookie: better-auth.session_token=..."

Current Month (Default)

# Defaults to current year and month
curl "https://your-domain.com/api/summary" \
  -H "Cookie: better-auth.session_token=..."

Example Response

{
  "data": {
    "user": {
      "username": "octocat",
      "avatar_url": "https://avatars.githubusercontent.com/u/583231",
      "name": "The Octocat",
      "bio": "GitHub mascot",
      "public_repos": 8,
      "followers": 9500,
      "total_stars": 15420
    },
    "year": 2024,
    "overview": {
      "totalCommits": 87,
      "totalPRs": 12,
      "totalIssues": 5,
      "topLanguages": [
        {
          "language": "TypeScript",
          "bytes": 450000,
          "percentage": 62.5
        },
        {
          "language": "JavaScript",
          "bytes": 180000,
          "percentage": 25.0
        }
      ],
      "busiestMonth": { "month": "Mar", "count": 87 }
    },
    "hourlyActivity": {
      "9": 8,
      "10": 12,
      "14": 15,
      "15": 18
    },
    "dailyActivity": {
      "Monday": 18,
      "Tuesday": 15,
      "Wednesday": 12,
      "Thursday": 20,
      "Friday": 22
    },
    "streak": {
      "longest": 15,
      "totalActiveDays": 22,
      "mostActiveDay": {
        "date": "2024-03-15",
        "count": 8
      }
    },
    "topRepos": [
      {
        "name": "my-project",
        "owner": { "login": "octocat" },
        "description": "A cool project",
        "stars": 450,
        "language": "TypeScript"
      }
    ],
    "generatedAt": "2026-03-03T08:00:00Z"
  }
}

Error Responses

{
  "error": "Invalid parameters"
}

Use Cases

Monthly Activity Dashboard

function MonthlyActivity() {
  const [summaries, setSummaries] = useState([]);
  const currentYear = 2024;
  
  useEffect(() => {
    // Fetch all 12 months
    Promise.all(
      Array.from({ length: 12 }, (_, i) => i + 1).map(month =>
        fetch(`/api/summary?year=${currentYear}&month=${month}`)
          .then(r => r.json())
      )
    ).then(results => {
      setSummaries(results.map(r => r.data));
    });
  }, []);
  
  return (
    <div>
      <h1>{currentYear} Monthly Activity</h1>
      {summaries.map((summary, i) => (
        <MonthCard 
          key={i}
          month={i + 1}
          commits={summary.overview.totalCommits}
          prs={summary.overview.totalPRs}
        />
      ))}
    </div>
  );
}

Current vs Previous Month Comparison

async function compareMonths() {
  const now = new Date();
  const currentMonth = now.getMonth() + 1;
  const currentYear = now.getFullYear();
  
  const previousMonth = currentMonth === 1 ? 12 : currentMonth - 1;
  const previousYear = currentMonth === 1 ? currentYear - 1 : currentYear;
  
  const [current, previous] = await Promise.all([
    fetch(`/api/summary?year=${currentYear}&month=${currentMonth}`)
      .then(r => r.json()),
    fetch(`/api/summary?year=${previousYear}&month=${previousMonth}`)
      .then(r => r.json())
  ]);
  
  const commitChange = 
    current.data.overview.totalCommits - previous.data.overview.totalCommits;
  
  console.log(`Commit change: ${commitChange > 0 ? '+' : ''}${commitChange}`);
}

Activity Calendar

function ActivityCalendar() {
  const [monthData, setMonthData] = useState(null);
  const [selectedMonth, setSelectedMonth] = useState(new Date().getMonth() + 1);
  const [selectedYear, setSelectedYear] = useState(new Date().getFullYear());
  
  useEffect(() => {
    fetch(`/api/summary?year=${selectedYear}&month=${selectedMonth}`)
      .then(r => r.json())
      .then(result => setMonthData(result.data));
  }, [selectedMonth, selectedYear]);
  
  return (
    <div>
      <MonthPicker 
        month={selectedMonth}
        year={selectedYear}
        onChange={(m, y) => {
          setSelectedMonth(m);
          setSelectedYear(y);
        }}
      />
      
      {monthData && (
        <>
          <ActivityHeatmap data={monthData.dailyActivity} />
          <TopRepos repos={monthData.topRepos} />
          <LanguageBreakdown languages={monthData.overview.topLanguages} />
        </>
      )}
    </div>
  );
}

Comparison: Summary vs Performance

Feature/api/summary/api/performance
ScopeSingle monthFull year
GranularityMonth + YearYear only
Use CaseMonthly trackingAnnual review
Data DepthMonth-specificYear-wide trends

Implementation Details

The endpoint uses the generateUserWrappedForMonth analytics method:
const analytics = new AnalyticsEngine(github);
const wrappedData = await analytics.generateUserWrappedForMonth(
  ghUser.login,
  year,
  month
);
This method filters all user activity to the specified month, providing focused insights.

Caching

This endpoint does not cache responses because:
  • Data is user-specific and private
  • Monthly summaries are typically accessed for current/recent months
  • Users expect real-time data for their own accounts

Source Code

Implementation: app/api/summary/route.ts

User Performance

Full year performance metrics

User Wrapped

Query any user’s public wrapped data

User Repositories

List authenticated user’s repositories

Authentication

Learn about GitHub OAuth

Build docs developers (and LLMs) love