NUSMods API (Unofficial / Community)

Community-maintained, unofficial JSON API providing NUS module, course, and timetable data normalized by the NUSModifications open-source project. Provides module lists, module details, faculty/department listings, and lesson types organized by academic year and semester. Not an official NUS service.

Documentation

Specifications

Schemas & Data

Other Resources

OpenAPI Specification

nus-nusmods.yaml Raw ↑
openapi: 3.0.1
info:
  description: "NUSMods API contains data used to render <https://nusmods.com>. It includes data on modules\
    \ offered by NUS and their timetables, as well as information on the locations the classes take place\
    \ in. You are welcome to use and experiment with the data, which is extracted from official APIs provided\
    \ by the Registrar's Office.\n\nThe API consists of static JSON files scraped daily from the school's\
    \ APIs. This means it only partially follow REST conventions, and all resources are read only. All\
    \ successful responses will return JSON, and all endpoints end in `.json`.\n\nThe shape of the data\
    \ returned by these endpoints are designed for NUSMods in mind. If you have any questions or find\
    \ that you need the data in other shapes for other purposes, feel free to reach out to us:\n\n- **Telegram**:\
    \ <https://telegram.me/nusmods>\n- **Mailing list**: <[email protected]>\n\n## Fetching data\n\nAny\
    \ HTTP client can be used to fetch data from the API. HTTPS is preferred, but the server will also\
    \ respond to HTTP requests. The server supports HTTP 1.1 as well as HTTP 2 over HTTPS, and supports\
    \ gzip compression.\n\nThe API has no authentication, and is not rate limited. While the server can\
    \ respond to a large number of requests simultaneously, we request that you be polite with resource\
    \ usage so as not to disrupt nusmods.com, which relies on the same API server. In general there is\
    \ no need to fetch data from the API more than once per day, as that is the frequency at which we\
    \ update the data.\n\n[CORS](https://developer.mozilla.org/en-US/docs/Web/HTTP/CORS) headers are enabled\
    \ on all endpoints, so client-side JavaScript can use also use the API.\n\n## TypeScript types\n\n\
    Since the NUSMods is written in TypeScript, typings are available in the source for the scraper. These\
    \ may be easier to read than the documentation generated by Swagger.\n\n- Module types: <https://github.com/nusmodifications/nusmods/blob/master/scrapers/nus-v2/src/types/modules.ts>\n\
    - Venue types: <https://github.com/nusmodifications/nusmods/blob/master/scrapers/nus-v2/src/types/venues.ts>\n\
    \n## Data\n\nBelow are some notes about the data returned from the API. Feel free to talk to us or\
    \ create an issue if any of it is not clear.\n\n### Module data\n\nModule endpoints return information\
    \ on modules offered by NUS. Most of the module data is self-explanatory, but some of the data are\
    \ more complex and is explained here.\n\n#### Lessons\n\nEach lesson in a timetable has a lesson type\
    \ `lessonType` and class number `ClassNo`. Every student must take one of each lesson type offered\
    \ by the module. For example, this module offers two tutorials and one lecture. That means the student\
    \ must attend the lecture, and can choose one of the two tutorials to attend.\n\n```json\n{\n  \"\
    timetable\": [\n    {\n      \"classNo\": \"1\",\n      \"lessonType\": \"Lecture\",\n      \"weeks\"\
    : [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],\n      \"day\": \"Tuesday\",\n      \"startTime\":\
    \ \"1600\",\n      \"endTime\": \"1800\",\n      \"venue\": \"I3-AUD\"\n    },\n    {\n      \"classNo\"\
    : \"01\",\n      \"lessonType\": \"Tutorial\",\n      \"weeks\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11,\
    \ 12, 13],\n      \"day\": \"Wednesday\",\n      \"startTime\": \"1100\",\n      \"endTime\": \"1200\"\
    ,\n      \"venue\": \"COM1-0207\"\n    },\n    {\n      \"classNo\": \"02\",\n      \"lessonType\"\
    : \"Tutorial\",\n      \"weeks\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],\n      \"day\": \"\
    Friday\",\n      \"startTime\": \"0900\",\n      \"endTime\": \"1000\",\n      \"venue\": \"COM1-0209\"\
    \n    }\n  ]\n}\n```\n\nEach lesson has a `classNo` key. There can be multiple lessons of the same\
    \ type and class number, in which case students must attend both. In this example, students can choose\
    \ to attend either lecture group 1 on Tuesdays and Wednesdays, or lecture group 2 on Mondays and Wednesdays.\n\
    \n```json\n{\n  \"timetable\": [\n    {\n      \"classNo\": \"1\",\n      \"lessonType\": \"Lecture\"\
    ,\n      \"weeks\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],\n      \"day\": \"Tuesday\",\n  \
    \    \"startTime\": \"1600\",\n      \"endTime\": \"1800\",\n      \"venue\": \"I3-AUD\"\n    },\n\
    \    {\n      \"classNo\": \"1\",\n      \"lessonType\": \"Lecture\",\n      \"weeks\": [1, 2, 3,\
    \ 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],\n      \"day\": \"Wednesday\",\n      \"startTime\": \"1400\"\
    ,\n      \"endTime\": \"1500\",\n      \"venue\": \"I3-AUD\"\n    },\n    {\n      \"classNo\": \"\
    2\",\n      \"lessonType\": \"Lecture\",\n      \"weeks\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12,\
    \ 13],\n      \"day\": \"Monday\",\n      \"startTime\": \"1000\",\n      \"endTime\": \"1200\",\n\
    \      \"venue\": \"I3-AUD\"\n    },\n    {\n      \"classNo\": \"2\",\n      \"lessonType\": \"Lecture\"\
    ,\n      \"weeks\": [1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12, 13],\n      \"day\": \"Wednesday\",\n\
    \      \"startTime\": \"1500\",\n      \"endTime\": \"1600\",\n      \"venue\": \"I3-AUD\"\n    }\n\
    \  ]\n}\n```\n\n#### Lesson Weeks\n\nThe `weeks` key on lessons can return data in one of two forms.\n\
    \nWeeks is usually a sorted array of numbers. In this case it represents the school weeks the lesson\
    \ occurs on, from 1 to 13.\n\nSome classes have lessons outside of the school timetable. In this case\
    \ a `WeekRange` object is returned. The object will always contain a `start` and `end` key representing\
    \ the start and end date of lessons. The example below has classes every week from 17th Jan to 18th\
    \ April.\n\n``` json\n\"weeks\": {\n  \"start\": \"2019-01-17\",\n  \"end\": \"2019-04-18\"\n}\n```\n\
    \nOptionally it can also include `weekInterval`, a positive integer describing the number of weeks\
    \ between each lesson, and `weeks`, an array of positive integers describing the weeks on which the\
    \ lesson will fall, with week 1 being the starting date. If these are not present you can assume lessons\
    \ will occur every week.\n\nThe following example has lessons on 17th Jan (week 1), 24th Jan (week\
    \ 2), 7th Feb (week 4) and 21st Feb (week 6).\n\n``` json\n\"weeks\": {\n  \"start\": \"2019-01-17\"\
    ,\n  \"end\": \"2019-02-21\",\n  \"weeks\": [1, 2, 4, 6]\n}\n```\n\nThe following example has lessons\
    \ on 17th Jan (week 1), 31st Jan (week 3), 14th Feb (week 5) and 28th Feb (week 7).\n\n``` json\n\"\
    weeks\": {\n  \"start\": \"2019-01-17\",\n  \"end\": \"2019-02-28\",\n  \"weekInterval\": 2\n}\n```\n\
    \n#### Workload\n\nThe `workload` key can return data in one of two forms.\n\nWorkload is usually\
    \ a **5-tuple of numbers**, describing the estimated number of hours per week the student is expected\
    \ to put in for the module for **lectures, tutorials, laboratory, projects/fieldwork, and preparatory\
    \ work** respectively. For example, a workload of `[2, 1, 1, 3, 3]` means the student should spend\
    \ every week\n\n- 2 hours in lectures\n- 1 hour in tutorials\n- 1 hour at the lab\n- 3 hours doing\
    \ project work\n- 3 hours preparing for classes\n\nEach module credit represents 2.5 hours of work\
    \ each week, so the standard 4 MC module represents 10 hours of work each week. Module credit may\
    \ not be integers.\n\nNote that this is only an estimate, and may be outdated or differ significantly\
    \ in reality. Some modules also incorrectly lists the **total** workload hours instead of weekly,\
    \ so very large values may show up.\n\nThis value is parsed from a string provided by the school,\
    \ and occasionally this field will contain unusual values which cannot be parsed. In this case this\
    \ field will contain the original **string** instead, which should be displayed as-is to the user.\n\
    \n#### Prerequisite, corequisite and preclusions\n\nThese three keys determine whether a student can\
    \ take a module.\n\n**Prerequisites** are requirements you have to meet before you can take a module.\
    \ These are usually in the form of other modules (see prerequisite tree below for a machine readable\
    \ format), but can also be things like 'taken A-level H2 math' or '70 MCs and above'.\n\n**Preclusions**\
    \ refer to modules or requirements that cannot be taken if this module is taken, and vice versa. These\
    \ are usually modules whose content overlaps significantly with this module, and can usually be used\
    \ to replace each other to fulfill prerequisites.\n\n**Corequisites** are modules that must be taken\
    \ together with this module in the same semester. This usually refer to twined modules - modules which\
    \ have linked syllabuses.\n\n#### Prerequisite Tree\n\nThe `prereqTree` key is return on the individual\
    \ module endpoint (`/modules/{moduleCode`). Not all modules have prerequisites, and some have prerequisites\
    \ that cannot be properly represented as a tree, in which case this key will not appear.\n\nThis describes\
    \ the prerequisites that need to be fulfilled before this module can be taken. The data structure\
    \ is recursive and represents a tree.\n\n```json\n{\n  \"and\": [\n    \"CS1231\",\n    {\n      \"\
    or\": [\"CS1010S\", \"CS1010X\"]\n    }\n  ]\n}\n```\n\nIn the example, this module requires CS1231\
    \ and either CS1010S or CS1010X. This can be visualized as\n\n```\n           ┌ CS1231\n── all of\
    \ ─┤\n           │         ┌ CS1010\n           └ one of ─┤\n                     └ CS1010X\n```\n\
    \nThe module information also contains the inverse of this, that is, modules whose requirements are\
    \ fulfilled by this module (taking this module will allow you to take these modules in the following\
    \ semester). The data is found on the `fulfillRequirements` key as an array of module codes.\n\n###\
    \ Venue data\n\nVenue data is simply the module timetable restructured to show the lessons happening\
    \ at each classroom.\n\nThe venue list endpoint returns a list of all locations that are used in the\
    \ semester. Note that this is not a comprehensive list of locations, but rather just a list of venues\
    \ that appears in module lessons.\n\nThe venue information endpoint returns the full class and occupancy\
    \ information about a venue. The `classes` key contains a list of lessons similar to the `timetable`\
    \ key in module data, but without a `venue` key and with `moduleCode`.\n"
  title: NUSMods API
  version: 2.0.0
  contact:
    email: [email protected]
servers:
- url: https://api.nusmods.com/v2
- url: http://api.nusmods.com/v2
tags:
- name: Modules
- name: Venues
paths:
  /{acadYear}/moduleList.json:
    summary: Module list
    get:
      summary: Get summaries of all modules
      description: 'Get the module code, title and semesters which the module is available in for all
        modules in a year. This is useful for tasks that only require a minimal set of information, such
        as simple search, autocompleting module code and titles, and checking if a module code is valid.


        NUSMods uses this information to validate module codes and for searching.

        '
      tags:
      - Modules
      parameters:
      - $ref: '#/components/parameters/acadYear'
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ModuleCondensed'
        404:
          $ref: '#/components/responses/404'
  /{acadYear}/moduleInformation.json:
    get:
      deprecated: true
      summary: Get detailed information about all modules
      description: 'Get all information about modules except for timetable and prereq tree in a year.
        This is compact enough to be loaded and filtered in browsers without lag and is useful for faceted
        search and detailed module listing.


        In AY2018/2019, NUSMods used this information for the detailed module search page. This endpoint
        will no longer be present starting in AY2019/2020. Please use the moduleInfo.json endpoint instead,
        which contains modules which are not offered in the specified academic year, but is otherwise
        identical to this endpoint.

        '
      parameters:
      - $ref: '#/components/parameters/acadYear'
      tags:
      - Modules
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ModuleInformation'
        404:
          $ref: '#/components/responses/404'
  /{acadYear}/moduleInfo.json:
    get:
      summary: Get detailed information about all modules
      description: 'Get all information about modules except for timetable and prereq tree in a year.
        This is compact enough to be loaded and filtered in browsers without lag and is useful for faceted
        search and detailed module listing.


        NUSMods feeds this information into an Elasticsearch search server for the detailed module search
        page.

        '
      parameters:
      - $ref: '#/components/parameters/acadYear'
      tags:
      - Modules
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  $ref: '#/components/schemas/ModuleInformation'
        404:
          $ref: '#/components/responses/404'
  /{acadYear}/modules/{moduleCode}.json:
    get:
      summary: Get all information about a specific module
      description: 'Get all information available for a specific module including prerequite tree and
        timetable.


        NUSMods uses this on the module information page.

        '
      parameters:
      - $ref: '#/components/parameters/acadYear'
      - $ref: '#/components/parameters/moduleCode'
      tags:
      - Modules
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Module'
        404:
          $ref: '#/components/responses/404'
  /{acadYear}/semesters/{semester}/venues.json:
    get:
      summary: Get a list of all venues
      parameters:
      - $ref: '#/components/parameters/acadYear'
      - $ref: '#/components/parameters/semester'
      description: 'Get a list of all venues, including lecture theatres, seminar rooms, laboratories,
        etc. used in the given semester''s classes. This endpoint only returns an array of names, and
        is useful for searching and autocompletion.

        '
      tags:
      - Venues
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                type: array
                items:
                  type: string
                  example: LT19
        404:
          $ref: '#/components/responses/404'
  /{acadYear}/semesters/{semester}/venueInformation.json:
    get:
      summary: Get detailed information on all venues
      parameters:
      - $ref: '#/components/parameters/acadYear'
      - $ref: '#/components/parameters/semester'
      description: 'Get detailed venue information including classes and occupancy for every venue. This
        is useful for displaying a timetable of the given venue as well as for checking if a venue is
        occupied at any given time.

        '
      tags:
      - Venues
      responses:
        200:
          description: Success
          content:
            application/json:
              schema:
                type: object
                additionalProperties:
                  type: array
                  items:
                    $ref: '#/components/schemas/VenueInformation'
                example:
                  LT19:
                  - day: Monday
                    classes:
                    - classNo: '1'
                      startTime: '1830'
                      endTime: '2030'
                      weeks:
                      - 1
                      - 2
                      - 3
                      - 4
                      - 5
                      - 6
                      - 7
                      - 8
                      - 9
                      - 10
                      - 11
                      - 12
                      - 13
                      day: Wednesday
                      lessonType: Lecture
                      moduleCode: CS5322
                      size: 40
                    availability:
                      0900: occupied
                      0930: occupied
                      1000: occupied
        404:
          $ref: '#/components/responses/404'
components:
  responses:
    404:
      description: Not found
  parameters:
    acadYear:
      name: acadYear
      in: path
      description: academic year, with the slash (/) replaced by a dash
      required: true
      schema:
        type: string
        example: 2018-2019
    moduleCode:
      name: moduleCode
      in: path
      description: module code
      required: true
      schema:
        type: string
        example: CS1010S
    semester:
      name: semester
      in: path
      description: semester, with 1 and 2 representing semester 1 and 2, and 3, 4 representing special
        term 1 and 2
      required: true
      schema:
        type: number
        enum:
        - 1
        - 2
        - 3
        - 4
  schemas:
    VenueInformation:
      properties:
        day:
          type: string
          enum:
          - Monday
          - Tuesday
          - Wednesday
          - Thursday
          - Friday
          - Saturday
        classes:
          type: array
          items:
            $ref: '#/components/schemas/VenueLesson'
        availability:
          type: object
          additionalProperties:
            enum:
            - occupied
          example:
            0900: occupied
            0930: occupied
            1000: occupied
    VenueLesson:
      allOf:
      - $ref: '#/components/schemas/Lesson'
      - type: object
        required:
        - moduleCode
        properties:
          moduleCode:
            type: string
            example: CS1010S
    PrereqTree:
      oneOf:
      - type: string
        example: CS1010S
      - type: object
        required:
        - or
        properties:
          or:
            type: array
            items:
              $ref: '#/components/schemas/PrereqTree'
      - type: object
        required:
        - and
        properties:
          and:
            type: array
            items:
              $ref: '#/components/schemas/PrereqTree'
      - type: object
        required:
        - nOf
        properties:
          nOf:
            type: array
            minItems: 2
            maxItems: 2
            items:
            - type: number
              description: Number of prerequisites required
            - type: array
              items:
                $ref: '#/components/schemas/PrereqTree'
            example:
            - 2
            - - CS1010
              - CS2100
              - CS2103T
      example:
        and:
        - or:
          - CS1010S
          - CS1010X
        - CS1231
    Workload:
      oneOf:
      - type: array
        items:
          type: number
        example:
        - 3
        - 1
        - 1
        - 3
        - 2
      - type: string
        example: A good background in the topics selected
    WeekRange:
      required:
      - start
      - end
      properties:
        start:
          type: string
          format: date
          example: '2019-01-17'
        end:
          type: string
          format: date
          example: '2019-06-20'
        weekInterval:
          type: number
          example: 2
          default: 1
        weeks:
          type: array
          items:
            type: number
          example:
          - 1
          - 2
          - 4
          - 5
          - 6
    Lesson:
      required:
      - classNo
      - startTime
      - endTime
      - weeks
      - venue
      - lessonType
      properties:
        classNo:
          type: string
          example: 08
        startTime:
          type: string
          example: '1100'
        endTime:
          type: string
          example: '1200'
        weeks:
          oneOf:
          - $ref: '#/components/schemas/WeekRange'
          - type: array
            items:
              type: number
            example:
            - 1
            - 2
            - 3
            - 4
            - 5
            - 6
            - 7
            - 8
            - 9
            - 10
            - 11
            - 12
            - 13
        venue:
          type: string
          example: COM1-0208
        day:
          type: string
          example: Friday
        lessonType:
          type: string
          example: Tutorial
        size:
          type: number
          example: 30
    ModuleCondensed:
      required:
      - moduleCode
      - title
      - semesters
      properties:
        moduleCode:
          type: string
          example: EL1101E
        title:
          type: string
          example: The Nature of Language
        semesters:
          type: array
          items:
            type: number
            enum:
            - 1
            - 2
            - 3
            - 4
          example:
          - 1
          - 2
    SemesterData:
      required:
      - semester
      properties:
        semester:
          type: number
          example: 1
        examDate:
          type: string
          format: date-time
          example: '2018-11-27T09:00:00.000Z'
        examDuration:
          type: number
          example: 120
        timetable:
          type: array
          items:
            $ref: '#/components/schemas/Lesson'
    Module:
      required:
      - acadYear
      - description
      - title
      - department
      - faculty
      - workload
      - moduleCredit
      - moduleCode
      - semesterData
      properties:
        acadYear:
          type: string
          example: 2018/2019
        preclusion:
          type: string
          example: CS1104 or Students from department of ECE
        description:
          type: string
          example: The objective of this module is to familiarise students with the fundamentals of computing
            devices. Through this module students will understand the basics of data representation, and
            how the various parts of a computer work, separately and with each other. This allows students
            to understand the issues in computing devices, and how these issues affect the implementation
            of solutions. Topics covered include data representation systems, combinational and sequential
            circuit design techniques, assembly language, processor execution cycles, pipelining, memory
            hierarchy and input/output systems.
        title:
          type: string
          example: Computer Organisation
        department:
          type: string
          example: Computer Science
        faculty:
          type: string
          example: Computing
        workload:
          $ref: '#/components/schemas/Workload'
        prerequisite:
          type: string
          example: CS1010 or its equivalent
        moduleCredit:
          type: string
          example: '4'
        moduleCode:
          type: string
          example: CS2100
        semesterData:
          type: array
          items:
            $ref: '#/components/schemas/SemesterData'
        prereqTree:
          $ref: '#/components/schemas/PrereqTree'
        fulfillRequirements:
          type: array
          items:
            type: string
          example:
          - CS2106
          - CS3210
    ModuleInformation:
      required:
      - moduleCode
      - title
      - description
      - moduleCredit
      - department
      - faculty
      - workload
      - semesterData
      properties:
        moduleCode:
          type: string
          example: CS2100
        title:
          type: string
          example: Computer Organisation
        description:
          type: string
          example: The objective of this module is to familiarise students with the fundamentals of computing
            devices. Through this module students will understand the basics of data representation, and
            how the various parts of a computer work, separately and with each other. This allows students
            to understand the issues in computing devices, and how these issues affect the implementation
            of solutions. Topics covered include data representation systems, combinational and sequential
            circuit design techniques, assembly language, processor execution cycles, pipelining, memory
            hierarchy and input/output systems.
        moduleCredit:
          type: string
          example: '4'
        department:
          type: string
          example: Computer Science
        faculty:
          type: string
          example: Computing
        workload:
          $ref: '#/components/schemas/Workload'
        prerequisite:
          type: string
          example: CS1010 or its equivalent
        preclusion:
          type: string
          example: CS1104 or Students from department of ECE
        corequisite:
          type: string
          example: Students must take CS2101 in the same semester as this module
        semesterData:
          type: array
          items:
            type: object
            properties:
              semester:
                type: number
                example: 1
              examDate:
                type: string
                format: date-time
                example: '2018-11-27T09:00:00.000Z'
              examDuration:
                description: Duration of the exam in minutes
                type: number
                example: 120