Skip to main content

Get Timetable

Retrieve one timetable in full: its bell schedules, entities, lessons and every lesson unit.

Endpoint​

GET /api/v1/timetables/{id}

ERP partners read timetables at GET /api/partner/v1/timetables/{id}. See Reading schedules.

Authentication​

Authorization: Bearer ttm_YOUR_API_KEY

See Authentication.

Path parameters​

ParameterTypeDescription
idstringTimetable id, from List Timetables

How the response fits together​

  • Bell schedules define the days and periods. A placement is a (dayId, periodIndex) pair.
  • Entities (teachers, subjects, classes, rooms) are listed once each.
  • Lessons say who teaches what to whom. Lesson units are the individual scheduled periods of a lesson.

Every reference in the response (a unit's teachers, a class's class teacher, a section's students) is a localId, and every localId it references is listed in the same response. To render a grid, walk lessonUnits, place each at its (dayId, periodIndex), and look up its teacherIds, classIds, subjectIds and roomIds in the entity lists.

Identifiers​

Each entity carries three identifiers:

FieldScopeUse it for
localIdThis timetable responseJoining references to entities. Every *Ids field holds these
entityIdYour organisation, across all timetablesRecognising the same teacher, class or room in another timetable or version
externalIdYour own systemsJoining to your own records (a staff number, a student MIS id). null when none is kept

Prefixes tell the entity type apart: tch_ teacher, cls_ class, sub_ subject, rom_ room, stu_ student, crs_ course. Treat the rest of an id as opaque.

Response​

{
"success": true,
"data": {
"id": "6a34108b1d16898202940188",
"name": "Term 1 2026",
"groupId": "6a3410551d16898202940101",
"versionNumber": 3,
"versionName": null,
"status": "published",
"isCurrent": true,
"publishedAt": "2026-08-28T07:15:00.000Z",
"effectiveFrom": 20260901,
"effectiveTo": null,
"schedulingMode": "standard",
"createdAt": "2026-07-01T09:12:00.000Z",
"updatedAt": "2026-08-28T07:15:00.000Z",
"description": "",
"orgId": "6913a0c4e1b2f3a4b5c6d7e8",

"bellSchedule": { "id": "bs_6a34108b1d16898202940188", "name": "Main", "isDefault": true, "…": "…" },
"bellSchedules": [
{
"id": "bs_6a34108b1d16898202940188",
"name": "Main",
"isDefault": true,
"scheduleType": "weekly",
"cycleLength": 1,
"days": [
{ "id": "day_w_0_d_1", "label": "Monday", "shortLabel": "Mon", "dayOfWeek": 1, "weekInCycle": null }
],
"dayConfigurations": [
{
"id": "dc1",
"dayIds": ["day_w_0_d_1"],
"periods": [
{ "id": "p1", "name": "Period 1", "startTime": "08:30", "endTime": "09:15" },
{ "id": "p2", "name": "Period 2", "startTime": "09:15", "endTime": "10:00" }
],
"breaks": [
{ "id": "b1", "name": "Break", "startTime": "10:00", "endTime": "10:20", "followsPeriodIndex": 1 }
]
}
]
}
],

"teachers": [
{ "localId": "tch_68d0f1…", "entityId": "68d0f1…", "externalId": "EMP-1001",
"name": "Ada Sharma", "shortName": "AS", "color": "#3B82F6", "isActive": true, "maxPeriods": 6 }
],
"subjects": [
{ "localId": "sub_6923ab…", "entityId": "6923ab…", "externalId": null,
"name": "Mathematics", "shortName": "Math", "color": "#10B981", "isActive": true }
],
"classes": [
{ "localId": "cls_6911cd…", "entityId": "6911cd…", "externalId": null,
"name": "Grade 9A", "shortName": "9A", "color": null, "isActive": true,
"classTeacherId": "tch_68d0f1…", "bellScheduleId": null }
],
"rooms": [
{ "localId": "rom_6930ef…", "entityId": "6930ef…", "externalId": null,
"name": "Science Lab", "shortName": "Lab", "color": null, "isActive": true,
"capacity": 30, "buildingName": "Main Block" },
{ "localId": "rom_6930f0…", "entityId": "6930f0…", "externalId": null,
"name": "Physics Lab", "shortName": "Phy", "color": null, "isActive": true,
"capacity": 28, "buildingName": "Main Block" }
],
"roomGroups": [
{ "id": "rgp_6a01c2…", "entityId": "6a01c2…", "name": "Science Labs",
"memberIds": ["rom_6930ef…", "rom_6930f0…"] }
],

"lessons": [
{
"localId": "lsn_cecf12…",
"groups": [
{ "id": "g1", "name": null,
"teacherIds": ["tch_68d0f1…"], "classIds": ["cls_6911cd…"], "subjectIds": ["sub_6923ab…"],
"studentIds": [],
"roomMode": "any", "roomIds": [], "roomCandidateIds": [],
"roomGroupIds": ["rgp_6a01c2…"], "roomVariation": "same" }
],
"lessonConfigurations": [ { "id": "cfg1", "frequency": 2, "length": 2 } ],
"distributionGroupId": null
}
],

"lessonUnits": [
{
"localId": "lu_0001…",
"lessonLocalId": "lsn_cecf12…",
"sectionLocalId": null,
"dayId": "day_w_0_d_1",
"periodIndex": 0,
"spanId": "sp_91…",
"parallelGroupId": null,
"groupName": null,
"parallelGroupName": null,
"distributionGroupId": null,
"lessonGroupId": "g1",
"roomPickedBy": "system",
"locked": false,
"lockReason": null,
"teacherIds": ["tch_68d0f1…"],
"classIds": ["cls_6911cd…"],
"subjectIds": ["sub_6923ab…"],
"roomIds": ["rom_6930ef…"],
"studentIds": []
}
]
},
"timestamp": "2026-10-06T10:00:00.000Z"
}

Version fields​

FieldNotes
idThis version. Pass it back to this endpoint
nameThe timetable's name, shared by all its versions
groupIdShared by every version of the same timetable
versionNumber, versionNameWhich version this is. versionName is null unless one was given
statusdraft or published. Only show published timetables to staff and students
isCurrenttrue for the version currently in use
publishedAtWhen it was published, null for a draft
effectiveFrom, effectiveToThe dates a published version applies, as YYYYMMDD numbers. effectiveTo: null means open-ended
schedulingModestandard (class-based) or student-level (see below)

Bell schedules​

bellSchedules lists every bell schedule the timetable uses, the default first. bellSchedule is the default one, repeated for readers that only need one.

FieldNotes
idReferenced by a class's bellScheduleId
isDefaulttrue for the schedule every class runs on unless it names another
scheduleType, cycleLengthweekly, or a cycle of cycleLength weeks
days[].idWhat a lesson unit's dayId refers to. weekInCycle tells weeks of a cycle apart
dayConfigurationsWhich periods and breaks apply on which days. Days can differ
periods[]In order. A unit's periodIndex is the position in this list (0-based)
breaks[].followsPeriodIndexThe period a break comes after

A class with bellScheduleId: null runs on the default schedule. Read a unit's period times from the schedule of the class it belongs to.

Entity fields​

FieldNotes
localId, entityId, externalIdSee Identifiers
isActivefalse for an entity removed from the organisation but still used by this timetable
maxPeriodsTeachers: the most periods per scheduling cycle (student-level scheduling), null when not set
classTeacherIdClasses: the class teacher's localId
bellScheduleIdClasses: the bell schedule the class runs on, null for the default
capacity, buildingNameRooms

An entity that a lesson still references but that no longer exists in your organisation is listed with the name Unknown, so every reference still leads somewhere.

Room groups​

roomGroups[] lists the room groups this timetable's lessons use: rooms that can stand in for one another ("Science Labs"). A room can be in several groups.

FieldNotes
idWhat lesson groups and courses reference in roomGroupIds (rgp_…)
entityIdThe group in your organisation, stable across timetables
nameThe group's name
memberIdsThe rooms in the group, by localId; every one is listed in rooms

A published timetable keeps the groups as they were when it was published.

Lesson fields​

FieldNotes
groups[]Who is taught. Most lessons have one group; a split or parallel lesson has several, each with its own teachers, classes and rooms
groups[].roomModeWhat rooms the group needs: all (every room in roomIds, at once), any (one room from roomCandidateIds or from the rooms of the groups in roomGroupIds), or none
groups[].roomIdsWith all: the rooms needed. Empty otherwise
groups[].roomCandidateIds, groups[].roomGroupIdsWith any: the rooms and room groups to choose from
groups[].roomVariationWith any: same (one room for every occurrence) or vary (the room may change from one occurrence to the next). A double period always stays in one room
lessonConfigurations[]frequency (how many times a week) of length periods each. A lesson with frequency: 2, length: 2 is two double periods
distributionGroupIdLessons sharing this id are spread across the week as one, instead of each on its own

Lesson unit fields​

FieldNotes
lessonLocalIdThe lesson this unit belongs to
dayId, periodIndexPlacement. Both null when the unit could not be scheduled
spanIdA double (or longer) period is several units sharing this id. Duration = how many share it
parallelGroupId, parallelGroupNameUnits taught at the same time (options blocks, split groups)
groupNameWhich group within a parallel block
lessonGroupIdThe id of the lesson group this unit teaches (lessons[].groups[]), where its room requirement is
roomIdsThe room the unit was given. For a lesson with roomMode: any this is the room picked for this occurrence
roomPickedByFor roomMode: any: system (picked by scheduling) or user (chosen by hand); null otherwise
locked, lockReasonThe unit was placed or pinned by hand
teacherIds, classIds, subjectIds, roomIds, studentIdsReferences by localId

There is no length field on a unit: a double period is two units sharing a spanId.

Student-level timetables​

When schedulingMode is student-level, the response also includes:

FieldNotes
students[]localId, entityId, externalId, name, shortName, color, classId (a class localId), courseIds (course localIds)
courses[]localId (crs_…), entityId, name, courseCode, teacherIds, roomIds, roomGroupIds, roomVariation and the course's scheduling settings
sections[]localId, name, courseLocalId, capacity, isAutoGenerated, parallelGroupId, teacherIds, roomIds, roomPickedBy, studentIds. When the course's roomVariation is vary, a section usually has no roomIds (each lesson unit has its own room); one with roomPickedBy: "user" has its lessons pinned to its room
sectionSettingsHow sections were generated

A unit's sectionLocalId names its section, and its subjectIds can hold the section's course (crs_…).

Example​

curl -H "Authorization: Bearer ttm_YOUR_API_KEY" \
https://api.timetablemaster.com/api/v1/timetables/6a34108b1d16898202940188

Errors​

StatusCodeMeaning
401INVALID_API_KEYMissing, invalid, expired or revoked key, or API access is not enabled for your organisation
402ACCESS_EXPIRED, ACCOUNT_SUSPENDEDYour organisation's access has ended or is suspended
404TIMETABLE_NOT_FOUNDNo such timetable, or it belongs to another organisation
500INTERNAL_ERRORUnexpected server error

See Authentication errors for the response bodies.