Endpoint: GET /api/performance Authentication Required
Retrieve performance analytics for the currently authenticated user. This endpoint returns the same data structure as /api/wrapped/user but automatically uses the authenticated user’s GitHub account.
Authentication
This endpoint requires authentication. Users must be logged in via GitHub OAuth.
The endpoint:
Validates the user has an active session
Retrieves the GitHub access token from the session
Fetches the authenticated user’s GitHub profile
Generates wrapped data for that user
Request
Query Parameters
year
number
default: "Previous year"
Year to generate performance data for (2008 - current year) Example: 2024
Optional GitHub personal access token override Note : Typically not needed as the session token is used automatically.
Validation Rules
year: Integer between 2008 and current year
Response
The response structure is identical to /api/wrapped/user.
Complete user wrapped analytics data for the authenticated user See User Wrapped for full structure details.
Examples
Basic Request
cURL
JavaScript
TypeScript with React
curl "https://your-domain.com/api/performance?year=2024" \
-H "Cookie: better-auth.session_token=..."
Default Year (Current - 1)
curl "https://your-domain.com/api/performance" \
-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" : 847 ,
"totalPRs" : 52 ,
"totalIssues" : 28 ,
"topLanguages" : [
{
"language" : "TypeScript" ,
"bytes" : 2500000 ,
"percentage" : 58.3
},
{
"language" : "JavaScript" ,
"bytes" : 1200000 ,
"percentage" : 28.0
}
],
"busiestMonth" : { "month" : "Apr" , "count" : 125 }
},
"hourlyActivity" : {
"9" : 45 ,
"10" : 78 ,
"14" : 92 ,
"15" : 105
},
"dailyActivity" : {
"Monday" : 145 ,
"Tuesday" : 156 ,
"Wednesday" : 142 ,
"Thursday" : 138 ,
"Friday" : 120
},
"streak" : {
"longest" : 42 ,
"totalActiveDays" : 245 ,
"mostActiveDay" : {
"date" : "2024-04-15" ,
"count" : 28
}
},
"topRepos" : [
{
"name" : "my-awesome-project" ,
"owner" : { "login" : "octocat" },
"description" : "An awesome project" ,
"stars" : 1200 ,
"language" : "TypeScript"
}
],
"generatedAt" : "2026-03-03T08:00:00Z"
}
}
Error Responses
400 Bad Request
401 Unauthorized
500 Internal Server Error
{
"error" : "Invalid parameters"
}
Authentication Flow
The endpoint performs the following authentication steps:
// 1. Get session from request headers
const session = await auth . api . getSession ({
headers: await headers (),
});
if ( ! session ?. user ) {
return NextResponse . json (
{ error: "Authentication required" },
{ status: 401 }
);
}
// 2. Get GitHub access token from session
const githubToken = await auth . api . getAccessToken ({
headers: await headers (),
body: { providerId: "github" },
});
// 3. Get authenticated user's GitHub profile
const github = new GitHubService ( githubToken ?. accessToken );
const ghUser = await github . getAuthenticatedUser ();
// 4. Generate wrapped for that user
const wrappedData = await analytics . generateUserWrapped ( ghUser . login , year );
Feature /api/performance/api/wrapped/userAuthentication Required Optional User Selection Authenticated user only Any username Private Data Always included Requires auth Use Case Personal dashboard Public profiles
Use Cases
Personal Dashboard
function MyDashboard () {
const [ performance , setPerformance ] = useState ( null );
useEffect (() => {
fetch ( '/api/performance' )
. then ( r => r . json ())
. then ( result => setPerformance ( result . data ));
}, []);
return (
< div >
< h1 > My GitHub Performance </ h1 >
{ performance && (
<>
< StatCard
title = "Total Commits"
value = {performance.overview. totalCommits }
/>
< StatCard
title = "Longest Streak"
value = { ` ${ performance . streak . longest } days` }
/>
< LanguageChart
languages = {performance.overview. topLanguages }
/>
</>
)}
</ div >
);
}
Year Comparison
async function compareYears () {
const [ current , previous ] = await Promise . all ([
fetch ( '/api/performance?year=2024' ). then ( r => r . json ()),
fetch ( '/api/performance?year=2023' ). then ( r => r . json ())
]);
const commitGrowth =
current . data . overview . totalCommits - previous . data . overview . totalCommits ;
console . log ( `Commit growth: ${ commitGrowth } ` );
}
Caching
This endpoint does not cache responses because:
Data is user-specific and private
Users expect real-time data for their own accounts
Session-based requests are already optimized
Source Code
Implementation: app/api/performance/route.ts
User Wrapped Query any user’s public wrapped data
User Summary Get monthly activity summary
User Repositories List authenticated user’s repositories
Authentication Learn about GitHub OAuth