openapi: 3.2.0 info: title: UW-Madison Public Course Search UW Madison Public Course Search API version: '1' description: 'The JSON API behind UW-Madison''s public course and section search at https://public.enroll.wisc.edu/search. It is operated by the University of Wisconsin-Madison Office of the Registrar / DoIT on the institution''s own enroll.wisc.edu host, requires no authentication, and is the institution''s only openly callable course-catalog surface. This document is PROBED, not published. UW-Madison does not publish an OpenAPI for this API; every path, parameter and response field below was observed in a live request made on 2026-08-19 and is recorded only to the extent it was actually verified. Fields the probe did not exercise are deliberately absent rather than guessed.' contact: name: UW-Madison Office of the Registrar url: https://registrar.wisc.edu/ servers: - url: https://public.enroll.wisc.edu/api/search/v1 description: Public production course search (no authentication) tags: - name: UW Madison Public Course Search API paths: /: post: summary: Search courses for a term description: 'Full-text course search scoped to one term code. Verified live: returns a `found` total and a `hits` array of course documents.' operationId: searchCourses requestBody: required: true content: application/json: schema: $ref: '#/components/schemas/CourseSearchRequest' responses: '200': description: Search results content: application/json: schema: $ref: '#/components/schemas/CourseSearchResponse' '400': description: Malformed or missing request body tags: - UW Madison Public Course Search API components: schemas: CourseSearchResponse: type: object properties: success: type: boolean message: type: - string - 'null' found: type: integer description: Total matching courses. example: 226 hits: type: array items: $ref: '#/components/schemas/CourseHit' CourseHit: type: object description: Field set observed in live responses. Types are inferred from observed values; only field names are directly verified. properties: termCode: type: string courseId: type: string subject: type: object catalogNumber: type: string title: type: string description: type: string minimumCredits: type: number maximumCredits: type: number creditRange: type: string firstTaught: type: string lastTaught: type: string typicallyOffered: type: string currentlyTaught: type: boolean gradingBasis: type: string repeatable: type: string honors: type: string levels: type: array items: type: object breadths: type: array items: type: object generalEd: type: - object - 'null' coreGeneralEducation: type: - object - 'null' ethnicStudies: type: - object - 'null' foreignLanguage: type: - object - 'null' sustainability: type: - object - 'null' workplaceExperience: type: - object - 'null' lettersAndScienceCredits: type: - object - 'null' openToFirstYear: type: boolean gradCourseWork: type: boolean approvedForTopics: type: boolean topics: type: array items: type: object advisoryPrerequisites: type: - string - 'null' enrollmentPrerequisites: type: - string - 'null' courseRequirements: type: - object - 'null' courseDesignation: type: string courseDesignationRaw: type: string fullCourseDesignation: type: string fullCourseDesignationRaw: type: string allCrossListedSubjects: type: array items: type: object academicGroupCode: type: string catalogPrintFlag: type: boolean instructorProvidedContent: type: - string - 'null' lastUpdated: type: integer format: int64 catalogSort: type: string subjectAggregate: type: string CourseSearchRequest: type: object required: - selectedTerm properties: selectedTerm: type: string description: Term code from GET /terms. example: '1266' queryString: type: string example: computer science filters: type: array items: type: object page: type: integer example: 1 pageSize: type: integer example: 2 sortOrder: type: string example: SCORE x-operator: institution x-provenance: generated: '2026-08-19' method: probed source: https://public.enroll.wisc.edu/api/search/v1 note: 'Reverse-described from live unauthenticated responses. Not a UW-Madison publication and must never be counted as one. Probes: GET /terms (200, 499 bytes, 2 terms), GET /aggregate (200, 127,065 bytes), POST / (200, term 1266 "computer science" -> found=226; term 1272 -> found=932).'