Base URL: https://api.pantherwatch.app
Real-time GSU course availability, grade history, professor ratings, syllabi, watch lists, and schedules. Public endpoints can be called directly; protected endpoints require a PantherWatch JWT.
PantherWatch issues its own JWT after Google sign-in. Start the browser flow at:
GET https://api.pantherwatch.app/api/auth/google/login
The backend redirects through Google and lands back on the app at /auth/callback#token=<jwt>. Send that token on protected endpoints:
Authorization: Bearer <your_pantherwatch_jwt>
Requests without a valid token get 401. Tokens expire after ~30 days.
/api/courses/termsAvailable registration terms. Descriptions ending in “(View Only)” are closed for registration.
[
{ "code": "202608", "description": "Fall Semester 2026" },
{ "code": "202601", "description": "Spring Semester 2026 (View Only)" }
]
curl -s https://api.pantherwatch.app/api/courses/terms
/api/courses/searchSearch course sections with live seat counts. Returns a paged result with a data array.
txtTerm — term code (required, see terms endpoint)txtSubject — subject code, e.g. CSC (required)txtCourseNumber — e.g. 1301 (required)txtLevel — US undergraduate / GS graduate (optional)pageOffset (default 0), pageMaxSize (default 200){
"success": true,
"totalCount": 3,
"data": [
{
"termDesc": "Fall Semester 2026",
"courseReferenceNumber": "89270",
"subject": "CSC",
"subjectDescription": "Computer Science",
"courseNumber": "1301",
"courseTitle": "Principles of Computer Science I",
"seatsAvailable": 5,
"enrollment": 20,
"maximumEnrollment": 25,
"waitCount": 0,
"faculty": [ { "displayName": "Doe, Jane" } ],
"meetingsFaculty": [ { "meetingTime": { "monday": true, "beginTime": "0930", "endTime": "1045" } } ]
}
]
}
curl -s "https://api.pantherwatch.app/api/courses/search?txtTerm=202608&txtSubject=CSC&txtCourseNumber=1301"
/api/courses/subjectsSubject-code autocomplete for a term.
searchTerm — prefix to match, e.g. CSterm — term codeoffset (default 1), max (default 10)curl -s "https://api.pantherwatch.app/api/courses/subjects?searchTerm=CS&term=202608"
/api/courses/gradesHistorical grade distribution for a course, aggregated across recent terms. With instructor, also resolves that professor's specific distribution.
subject, courseNumber — requiredinstructor — optional, display name as returned by searchcurl -s "https://api.pantherwatch.app/api/courses/grades?subject=CSC&courseNumber=1301&instructor=Doe,%20Jane"
/api/courses/ratingsRateMyProfessors summary for an instructor, resolved by name against GSU. Returns found: false when there's no profile.
curl -s "https://api.pantherwatch.app/api/courses/ratings?professor=Doe,%20Jane"
/api/courses/syllabusWhether a section has a published syllabus in GSU's repository, plus the embeddable PDF URL when it does.
curl -s "https://api.pantherwatch.app/api/courses/syllabus?term=202608&crn=89270"
Your seat-alert watch list. Watchers get one email per seat opening. All endpoints require Authorization: Bearer <token>.
/api/watched-classesYour current watch list.
{
"success": true,
"data": [
{
"id": 1,
"crn": "89270",
"term": "202608",
"courseTitle": "Principles of Computer Science I",
"courseNumber": "1301",
"subject": "CSC",
"instructor": "Doe, Jane",
"createdAt": "2026-07-01T12:34:56"
}
],
"count": 1
}
curl -s -H "Authorization: Bearer $TOKEN" https://api.pantherwatch.app/api/watched-classes
/api/watched-classesAdd a class to your watch list.
{
"crn": "89270",
"term": "202608",
"courseTitle": "Principles of Computer Science I",
"courseNumber": "1301",
"subject": "CSC",
"instructor": "Doe, Jane"
}
curl -s -X POST \
-H "Authorization: Bearer $TOKEN" \
-H "Content-Type: application/json" \
-d '{"crn":"89270","term":"202608","courseTitle":"Principles of Computer Science I","courseNumber":"1301","subject":"CSC","instructor":"Doe, Jane"}' \
https://api.pantherwatch.app/api/watched-classes
/api/watched-classes?crn=…&term=…Remove a class from your watch list.
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
"https://api.pantherwatch.app/api/watched-classes?crn=89270&term=202608"
/api/watched-classes/check?crn=…&term=…Whether you're watching a specific class. Returns { "success": true, "isWatching": true }.
/api/watched-classes/countNumber of classes you're watching. Returns { "success": true, "count": 3 }.
/api/watched-classes/full-detailsFull live course objects (same shape as search results) for every class on your watch list. Sections that can't be resolved come back as placeholders with isPartialData: true.
The Schedule Builder's cloud copy. The database stores course identity per entry; clients hydrate entries into full course objects via /api/courses/search.
/api/scheduleAll schedule entries for the current user, grouped by term code.
{
"202608": [
{
"id": 1,
"termCode": "202608",
"crn": "89270",
"subject": "CSC",
"courseNumber": "1301",
"courseTitle": "Principles of Computer Science I",
"addedAt": "2026-07-01T12:34:56"
}
]
}
curl -s -H "Authorization: Bearer $TOKEN" https://api.pantherwatch.app/api/schedule
/api/scheduleAdd a course to your schedule. Rejected with 400 for view-only terms.
{
"termCode": "202608",
"crn": "89270",
"subject": "CSC",
"courseNumber": "1301",
"courseTitle": "Principles of Computer Science I"
}
/api/schedule/{termCode}/{crn}Remove a course from your schedule.
curl -s -X DELETE -H "Authorization: Bearer $TOKEN" \
https://api.pantherwatch.app/api/schedule/202608/89270
/api/announcements/active publicCurrently active site-wide announcements (shown as the banner in the app).
Creating, updating, activating, and deleting announcements is admin-only.
/api/users/mePermanently delete your account and all related data (watch list, schedule).
Restricted to configured admin accounts; regular tokens get 403.
GET /api/admin/check — whether the current user is an adminGET /api/admin/users, POST /api/admin/users/search — user administrationPOST /api/admin/email/send, GET /api/admin/emails/stats, POST /api/admin/emails/cleanup — email toolingPOST /api/admin/grades/refresh, GET /api/admin/grades/status — grade-data pipeline/api/announcements management (create / update / activate / deactivate / delete){ "success": false, "message": "…" }.courseReferenceNumber.pantherwatch.app origins and localhost dev ports.