New: see the walk between your classes on the timetable

Build with the data

Data reference

How the files fit together and what the fields mean. The field tables themselves are in the REST API page.

The files#

PathWhat it holdsShape
/api/modules/{code}One module, in full.A single object.
/data/api/modules.jsonEvery module since AY2014, one summary row each, with its latest offering.An object with a list called modules.
/data/api/indexes/{year_semester}.jsonEvery class index in one semester.Module code, then index number, then a list of class slots.
/data/api/exams/{year_semester}.jsonThe exam timetable for one semester.Module code, then one exam.

Every field of each file is listed in the REST API reference. All files are served from https://ntumods.com.

Semester codes#

  • A semester is written year_semester, such as 2026_2. The year is the academic year, so 2026 is AY2026/27.
  • The semester is 1, 2or S (special term). Older files, up to 2021, also have T for the second special term.
  • The newest semester with classes and the newest with an exam timetable are often different. Exams are published later, so an exam file can be empty ({}) for a new semester.

How the files join#

  • The module code is the key in every file. Use it to go from a row in modules.json to its class indexes and exam.
  • A class index is one group of classes a student picks, such as a lecture with one tutorial. It has a number, such as 10052, and a list of class slots. A student picks one index per module.
  • Index numbers are text and are unique within a semester, not across semesters.

Class slots#

One class slot
{  "key": "10052",  "type": "LEC",  "group": "SCL1",  "day": 3,  "time": "0930-1120",  "venue": "LT3",  "remarks": "Teaching Wk1-9,11-13",  "duration": 4}
  • type is LEC, TUT, LAB, SEM and a few rarer ones such as PRJ and DES.
  • day counts from 1 for Monday to 6 for Saturday. A few slots have 0, which means online or to be announced, with no fixed time.
  • time is HHMM-HHMM on a 24 hour clock, with no colon and no time zone. It is Singapore time.
  • duration is in half hours, so 4 is two hours.
  • remarks is NTU's own note and is empty when there is none. It often gives the weeks the class runs, such as Teaching Wk2-13, or alternate weeks such as Teaching Wk2,4,6,8,10,12. It is free text, so do not rely on parsing it.

Exams#

One exam
{  "key": "SC1004",  "name": "LINEAR ALGEBRA FOR COMPUTING",  "date": "23 November 2026",  "day": 1,  "start_time": "5.00 pm",  "end_time": "7.00 pm",  "duration": 4}
  • date, start_time andend_time are text as NTU writes them. Times use a dot, as in9.00 am, not a colon.
  • day counts from 1 for Monday to 7 for Sunday, and duration is in half hours.
  • Venues and seats are not published in this data.

Module records#

  • au is a number in /api/modules/{code} and text, such as "3.0", in modules.json.
  • prerequisites is a list of groups. Every group must be met, and any one module in a group meets it. In the example below you need (MH1812 or SC1007) and (SC1007 or SC1124). A code with a suffix, such as SC1003(Corequisite), may be taken at the same time.
  • requires flattens the groups, and requiredBy lists the modules that need this one.
  • categories uses COREfor programme core, GLOAD for BDE, MLOAD for a minor,GERP for general education, and a few others.
  • The restrictions fields are free text exactly as NTU publishes them, or null. description, gradeType and school can also be null. Lists are empty, not null.
  • exam is null when no exam timetable is published for the latest offering.
From SC2001
"prerequisites": [["MH1812", "SC1007"], ["SC1007", "SC1124"]]

Found something wrong?

NTUMods is built and maintained by one person, so a short note goes a long way. Pick what fits, add the details, and I will look at it.

I'll use this to follow up with you.

Attaches your saved timetables and settings to help debug the issue. On by default, turn off to exclude it.

Developer? Open an issue or PR.