PantherWatch API

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.

Authentication

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.

Courses public

GET /api/courses/terms

Available 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
GET /api/courses/search

Search course sections with live seat counts. Returns a paged result with a data array.

Query parameters:
  • txtTerm — term code (required, see terms endpoint)
  • txtSubject — subject code, e.g. CSC (required)
  • txtCourseNumber — e.g. 1301 (required)
  • txtLevelUS 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"
GET /api/courses/subjects

Subject-code autocomplete for a term.

  • searchTerm — prefix to match, e.g. CS
  • term — term code
  • offset (default 1), max (default 10)
curl -s "https://api.pantherwatch.app/api/courses/subjects?searchTerm=CS&term=202608"
GET /api/courses/grades

Historical grade distribution for a course, aggregated across recent terms. With instructor, also resolves that professor's specific distribution.

  • subject, courseNumber — required
  • instructor — optional, display name as returned by search
curl -s "https://api.pantherwatch.app/api/courses/grades?subject=CSC&courseNumber=1301&instructor=Doe,%20Jane"
GET /api/courses/ratings

RateMyProfessors 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"
GET /api/courses/syllabus

Whether 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"

Watched classes protected

Your seat-alert watch list. Watchers get one email per seat opening. All endpoints require Authorization: Bearer <token>.

GET /api/watched-classes

Your 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
POST /api/watched-classes

Add 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
DELETE /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"
GET /api/watched-classes/check?crn=…&term=…

Whether you're watching a specific class. Returns { "success": true, "isWatching": true }.

GET /api/watched-classes/count

Number of classes you're watching. Returns { "success": true, "count": 3 }.

GET /api/watched-classes/full-details

Full 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.

Schedule protected

The Schedule Builder's cloud copy. The database stores course identity per entry; clients hydrate entries into full course objects via /api/courses/search.

GET /api/schedule

All 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
POST /api/schedule

Add 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"
}
DELETE /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

Announcements

GET /api/announcements/active public

Currently active site-wide announcements (shown as the banner in the app).

Creating, updating, activating, and deleting announcements is admin-only.

Account protected

DELETE /api/users/me

Permanently delete your account and all related data (watch list, schedule).

Admin admin only

Restricted to configured admin accounts; regular tokens get 403.

Notes