GET /api/auth/github, which sends the browser to GitHub’s authorization page. After the user approves access, GitHub redirects back to GET /api/auth/github/callback with a one-time code. The server exchanges that code for a GitHub access token, upserts a user record, signs a JWT, and redirects the browser to your frontend with the token in the query string. Neither endpoint requires an existing JWT — they are the mechanism that produces one.
GET /api/auth/github
Redirects the browser to GitHub’s OAuth authorization page. No request body or authentication is needed. No auth required. When the user visits this URL, the server responds with302 and sets the Location header to:
prompt=consent parameter forces the GitHub authorization screen to appear even if the user previously authorized the app, so they always see which scopes are being requested.
Requested scopes
Curl example
Visiting this URL in a browser is the intended use. To inspect the redirect target without following it:GET /api/auth/github/callback
Handles the OAuth callback from GitHub. GitHub appends a one-timecode to this URL after the user authorizes the app. The server exchanges the code for an access token, fetches the user’s GitHub profile, upserts a user record in the database, signs a JWT, and redirects the browser to FRONTEND_URL/auth/callback with the session data in the query string.
No auth required.
Query parameters
string
required
The one-time authorization code provided by GitHub after the user grants access. GitHub appends this to your callback URL automatically — you do not construct or send it yourself.
Success redirect
On success, the server responds with302 and redirects to:
Error responses
Handling the callback in your frontend
When the browser lands on your frontend’s/auth/callback route, parse the query parameters and store the token for subsequent API calls:
The JWT expires after 1 hour. When it expires, the user must go through the OAuth flow again — redirect them to
/api/auth/github to re-authenticate.