Download OpenAPI specification:
InsightUBC enables UBC administrators and researchers to analyze historical course offering data. Notes:
Deprecated. Use /api/v2/datasets.
Upload a zip archive for asynchronous processing. The data is normalized and added to existing resources in the system.
To bulk upload course offerings (combined course and section data flattened into a single record), make a multipart request with:
kind field set to "course_offerings".archive field set to a zip file with:a root directory named courses/
one or more JSON files inside courses/ (file names are arbitrary)
each JSON file has a result property whose value is an array of objects with the following partial schema of fields that must be present together with their expected type:
{
id: string,
Course: string,
Title: string,
Professor: string,
Subject: string,
Section: string,
Year: string,
Avg: number,
Pass: number,
Fail: number,
Audit: number
}
Once the upload is complete, the system asynchronously processes the uploaded archive. The upload job is tracked with a unique id that you can use to query the job status via the GET /api/v1/datasets/{id} endpoint. The processing follows these steps:
Validate zip format: The uploaded file is verified to be a valid zip archive. If not, the job status is set to failed with message "Data is not in a valid zip format".
Check for courses/ directory: The system checks for the existence of a root courses/ directory within the archive. If missing, the job status is set to failed with message "Missing root courses directory".
Process files in courses/ directory: For each file in the courses/ directory:
result property, each course offering object in the result array is processed according to the rules below.result property, the file is skipped.Load records into resources: For each result object that is processed, the following rules apply:
Courses: the course id is set to Subject + Course (the concatenation of the field values).
If the course does not exist, create a new course with:
code set to the offering's Course fieldtitle set to the most recent offering's Title fielddept set to the offering's Subject fieldIf the course exists, update it only if any field value in the mapping above differs from the current resource.
Sections: the section id is set to the course offering id.
If the section does not exist, create a new section under the course with:
instructor set to the offering's Professor fieldyear set to the offering's Year field, converted to a number (or 1900 when the offering's Section field equals "overall")avg set to the offering's Avg fieldpass set to the offering's Pass fieldfail set to the offering's Fail fieldaudit set to the offering's Audit fieldIf the section exists, update it only if any field value in the mapping above differs from the current resource.
A record will not be processed if any of the following conditions are met:
Note: Courses are processed before sections to ensure every section's parent course exists before the section is created or updated.
| kind required | string Value: "course_offerings" The type of data contained in the archive. |
| archive required | string <binary> A zip file containing the data to upload. |
Example multipart request uploading a zip file containing course offering data.
{ "kind": "course_offerings", "archive": "[binary zip file contents]" }
{- "id": "upload_12345",
- "status": "processing",
- "kind": "course_offerings",
- "message": "Dataset accepted for processing"
}Deprecated. Use /api/v2/datasets/{id}.
Retrieve the status and statistics of a dataset upload job. The status reflects the current processing state:
processing: The job is currently being processed according to the steps defined in the POST endpoint.completed: The job finished successfully. File statistics show how many files were processed vs skipped. Resource statistics show how many resources were created or modified during processing.failed: The job encountered a fatal error during validation. Check the message field for details (e.g., "Data is not in a valid zip format" or "Missing root courses directory").| id required | string Dataset upload job identifier |
{- "id": "upload_12345",
- "status": "completed",
- "kind": "course_offerings",
- "stats": {
- "files_total": 12,
- "files_processed": 10,
- "files_skipped": 2,
- "courses_seen": 50,
- "courses_added": 47,
- "courses_modified": 3,
- "sections_seen": 1612,
- "sections_added": 1523,
- "sections_modified": 89
}, - "message": "Dataset processing complete"
}Upload a zip archive for asynchronous processing. The data is normalized and added to existing resources in the system.
Important: This endpoint returns a 202 response immediately upon accepting the upload. All validation and processing steps described below happen asynchronously in the background. To check the status of processing or see any errors that occurred, query the GET /api/v2/datasets/{id} endpoint using the returned job id.
To bulk upload course offerings (combined course and section data flattened into a single record), make a multipart request with:
kind field set to "course_offerings".archive field set to a zip file with:a root directory named courses/
one or more JSON files inside courses/ (file names are arbitrary)
each JSON file has a result property whose value is an array of objects with the following partial schema of fields that must be present together with their expected type:
{
id: string,
Course: string,
Title: string,
Professor: string,
Subject: string,
Section: string,
Year: string,
Avg: number,
Pass: number,
Fail: number,
Audit: number
}
Course Offerings Processing Steps:
The following steps occur asynchronously after the upload is accepted. Check the GET /api/v2/datasets/{id} endpoint to monitor progress and see any errors.
Validate zip format: The uploaded file is verified to be a valid zip archive. If not, the job status is set to failed with message "Data is not in a valid zip format".
Check for courses/ directory: The system checks for the existence of a root courses/ directory within the archive. If missing, the job status is set to failed with message "Missing root courses directory".
Process files in courses/ directory: For each file in the courses/ directory:
result property, each course offering object in the result array is processed according to the rules below.result property, the file is skipped.Load records into resources: For each result object that is processed, the following rules apply:
Courses: the course id is set to Subject + Course (the concatenation of the field values).
If the course does not exist, create a new course with:
code set to the offering's Course fieldtitle set to the most recent offering's Title fielddept set to the offering's Subject fieldIf the course exists, update it only if any field value in the mapping above differs from the current resource.
Sections: the section id is set to the course offering id.
If the section does not exist, create a new section under the course with:
instructor set to the offering's Professor fieldyear set to the offering's Year field, converted to a number (or 1900 when the offering's Section field equals "overall")avg set to the offering's Avg fieldpass set to the offering's Pass fieldfail set to the offering's Fail fieldaudit set to the offering's Audit fieldIf the section exists, update it only if any field value in the mapping above differs from the current resource.
A record will not be processed if any of the following conditions are met:
Note: Courses are processed before sections to ensure every section's parent course exists before the section is created or updated.
To bulk upload facilities (rooms and buildings), make a multipart request with:
kind field set to "facilities".archive field set to a zip file with:index.htm file at the root of the zipindex.htmFacilities Processing Steps:
The following steps occur asynchronously after the upload is accepted. Check the GET /api/v2/datasets/{id} endpoint to monitor progress and see any errors.
Validate zip format: The uploaded file is verified to be a valid zip archive. If not, the job status is set to failed with message "Data is not in a valid zip format".
Validate index.htm: The system checks for the existence of index.htm at the root of the archive. If missing, the job status is set to failed with message "Missing index.htm file".
The file is then parsed to verify it is valid HTML. If it cannot be parsed, the job status is set to failed with message "index.htm could not be parsed".
Locate building table: A table with class views-table is located in the parsed index.htm. If no such table is found, the job status is set to failed with message "No building table found in index.htm".
Extract building information: For each row in the building table, the following information is extracted:
<a> element in the cell with class views-field-titleviews-field-field-building-codeviews-field-field-building-addresshref attribute from the <a> element in the cell with class views-field-titleExtract room information: For each link identified in index.htm:
views-table is located in the linked file<a> element in the cell with class views-field-field-room-numberviews-field-field-room-capacityviews-field-field-room-furnitureviews-field-field-room-typehref attribute from the <a> element in the cell with class views-field-nothingExtract geolocation information: For each building extracted in step 4:
index.htmerror, no geolocation information is available for that building and the building should be skipped.Load records into resources: For each building and its rooms that were successfully processed in steps 4-6, the following rules apply:
Buildings: the building id is set to shortname.
If the building does not exist, create a new building with:
name set to the building's fullnameaddress set to the building's addresslat set to the latitude from geolocationlon set to the longitude from geolocationIf the building exists, update it only if any field value in the mapping above differs from the current resource.
The resulting building resource is validated against the same requirements as building data added through PUT /api/v2/buildings/{building}. If required building data is missing or invalid, no building resource is loaded.
Rooms: the room id is set to shortname_number (the concatenation of building shortname, underscore, and room number).
If the room does not exist, create a new room under the building with:
building set to the building's shortnamenumber set to the room's number fieldseats set to the room's seats fieldtype set to the room's type fieldfurniture set to the room's furniture fieldhref set to the room's href fieldIf the room exists, update it only if any field value in the mapping above differs from the current resource.
The resulting room resource is validated against the same requirements as room data added through PUT /api/v2/buildings/{building}/rooms/{room}. If required room data is missing or invalid, no room resource is loaded.
Note: Buildings are processed before rooms to ensure every room's parent building exists before the room is created or updated.
| kind required | string Enum: "course_offerings" "facilities" The type of data contained in the archive. |
| archive required | string <binary> A zip file containing the data to upload. |
Example multipart request uploading a zip file containing course offering data.
{ "kind": "course_offerings", "archive": "[binary zip file contents]" }
{- "id": "upload_12345",
- "status": "processing",
- "kind": "course_offerings",
- "message": "Dataset accepted for processing"
}Retrieve the status and statistics of a dataset upload job. The status reflects the current processing state:
processing: The job is currently being processed according to the steps defined in the POST endpoint.completed: The job finished successfully. Statistics are kind-specific and report resource creation/modification outcomes during processing.failed: The job encountered a fatal error during validation. Check the message field for details (e.g., "Data is not in a valid zip format" or "Missing root courses directory" or "Missing root rooms directory").| id required | string Dataset upload job identifier |
{- "id": "upload_12345",
- "status": "completed",
- "kind": "course_offerings",
- "stats": {
- "files_total": 12,
- "files_processed": 10,
- "files_skipped": 2,
- "courses_seen": 50,
- "courses_added": 47,
- "courses_modified": 3,
- "sections_seen": 1612,
- "sections_added": 1523,
- "sections_modified": 89
}, - "message": "Dataset processing complete"
}Deprecated. Use /api/v2/search.
Execute a query using a JSON-based domain-specific language (DSL) to search resources.
The query object has three main components:
WHERE filters which records should be included in the results.COLUMNS selects which keys are included in each result.ORDER sorts the results by a key in COLUMNS.The DSL grammar is defined using EBNF:
QUERY ::='{' BODY ', ' OPTIONS '}'
// Note: a BODY with no FILTER (i.e. WHERE:{}) matches all entries.
BODY ::= 'WHERE:{' FILTER? '}'
FILTER ::= LOGICCOMPARISON | MCOMPARISON | SCOMPARISON | NEGATION
LOGICCOMPARISON ::= LOGIC ':[' FILTER_LIST ']'
MCOMPARISON ::= MCOMPARATOR ':{' mkey ':' number '}'
SCOMPARISON ::= 'IS:{' skey ': "' [*]? inputstring [*]? '" }' // Asterisks at the beginning or end of the inputstring should act as wildcards.
NEGATION ::= 'NOT :{' FILTER '}'
FILTER_LIST ::= '{' FILTER '}' | '{' FILTER '}, ' FILTER_LIST // comma separated list of filters containing at least one filter
LOGIC ::= 'AND' | 'OR'
MCOMPARATOR ::= 'LT' | 'GT' | 'EQ'
OPTIONS ::= 'OPTIONS:{' COLUMNS '}' | 'OPTIONS:{' COLUMNS ', ORDER:' key '}'
COLUMNS ::= 'COLUMNS:[' KEY_LIST ']'
KEY_LIST ::= key | key ', ' KEY_LIST // comma separated list of keys containing at least one key
key ::= mkey | skey
mkey ::= '"' mfield '"'
skey ::= '"' sfield '"'
mfield ::= 'avg' | 'pass' | 'fail' | 'audit' | 'year'
sfield ::= 'title' | 'dept' | 'code' | 'instructor'
inputstring ::= [^*]* // Zero or more of any character, except asterisk.
You can use optional asterisks (*) in IS comparisons to match patterns.
For example, "IS": {"dept": "C*"} matches any department that starts with "C".
Because the asterisks can appear at the beginning and/or end, there are four possible forms:
inputstring: Matches inputstring exactly
*inputstring: Ends with inputstring
inputstring*: Starts with inputstring
*inputstring*: Contains inputstring
Asterisks in the middle are not allowed (for example, input*string).
You can sort results by specifying the ORDER field with any key that appears in your COLUMNS list.
If ORDER is not specified, results may appear in any order.
Ties. When sorting produces tied values, the relative order of those entries is not guaranteed. For example, if you sort by department, all CPSC entries will be grouped together, but individual CPSC entries may appear in any order within that group.
| kind required | string Enum: "course_offerings" "facilities" The type of resource to query. |
| query required | object A query object that follows the DSL grammar defined in the EBNF. |
This query produces course offerings that have an average greater than 99.
{- "kind": "course_offerings",
- "query": {
- "WHERE": {
- "GT": {
- "avg": 99
}
}, - "OPTIONS": {
- "COLUMNS": [
- "dept",
- "avg"
], - "ORDER": "avg"
}
}
}Example search results for the simple query on the PAIR dataset that selects sections with an average greater than 99.
[- {
- "dept": "cnps",
- "avg": 99.19
}, - {
- "dept": "math",
- "avg": 99.78
}, - {
- "dept": "math",
- "avg": 99.78
}
]Execute a query using a JSON-based domain-specific language (DSL) to search resources.
The query object has three main components:
WHERE filters which records should be included in the results.COLUMNS selects which keys are included in each result.ORDER sorts the results by a key in COLUMNS.Important: All fields used in a query must belong to the same kind. You cannot mix course_offerings fields with facilities fields in a single query.
The DSL grammar is defined using EBNF:
QUERY ::='{' BODY ', ' OPTIONS '}' | '{' BODY ', ' OPTIONS ', ' TRANSFORMATIONS '}'
// Note: a BODY with no FILTER (i.e. WHERE:{}) matches all entries.
BODY ::= 'WHERE:{' FILTER? '}'
FILTER ::= LOGICCOMPARISON | MCOMPARISON | SCOMPARISON | NEGATION
LOGICCOMPARISON ::= LOGIC ':[' FILTER_LIST ']'
MCOMPARISON ::= MCOMPARATOR ':{' mkey ':' number '}'
SCOMPARISON ::= 'IS:{' skey ': "' [*]? inputstring [*]? '" }' // Asterisks at the beginning or end of the inputstring should act as wildcards.
NEGATION ::= 'NOT :{' FILTER '}'
FILTER_LIST ::= '{' FILTER '}' | '{' FILTER '}, ' FILTER_LIST // comma separated list of filters containing at least one filter
LOGIC ::= 'AND' | 'OR'
MCOMPARATOR ::= 'LT' | 'GT' | 'EQ'
OPTIONS ::= 'OPTIONS:{' COLUMNS '}' | 'OPTIONS:{' COLUMNS ', ' SORT '}'
SORT ::= 'ORDER: { dir:' DIRECTION ', keys: [ ' ANYKEY_LIST '] }' | 'ORDER: ' ANYKEY
DIRECTION ::= 'UP' | 'DOWN'
TRANSFORMATIONS ::= 'TRANSFORMATIONS: {' GROUP ', ' APPLY '}'
GROUP ::= 'GROUP: [' KEY_LIST ']'
APPLY ::= 'APPLY: [' APPLYRULE_LIST? ']'
APPLYRULE_LIST ::= APPLYRULE | APPLYRULE ', ' APPLYRULE_LIST
APPLYRULE ::= '{' applykey ': {' APPLYTOKEN ':' KEY '} }'
APPLYTOKEN ::= 'MAX' | 'MIN' | 'AVG' | 'COUNT' | 'SUM'
COLUMNS ::= 'COLUMNS:[' ANYKEY_LIST ']'
// Comma-separated list of keys containing at least one key
KEY_LIST ::= KEY | KEY ', ' KEY_LIST
ANYKEY_LIST ::= ANYKEY | ANYKEY ', ' ANYKEY_LIST
ANYKEY ::= KEY | applykey
KEY ::= mkey | skey
mkey ::= '"' mfield '"'
skey ::= '"' sfield '"'
inputstring ::= [^*]* // Zero or more of any character, except asterisk.
applykey ::= [^_]+ // One or more of any character, except underscore.
When querying course_offerings kind, use these fields:
mfield ::= 'avg' | 'pass' | 'fail' | 'audit' | 'year'
sfield ::= 'title' | 'dept' | 'code' | 'instructor'
When querying facilities kind, use these fields:
mfield ::= 'lat' | 'lon' | 'seats'
sfield ::= 'address' | 'building' | 'furniture' | 'href' | 'name' | 'number' | 'type'
The query language supports performing calculations across a group of results.
Supported Aggregation Functions:
Requirements:
The query language supports sorting by:
"ORDER": "avg""ORDER": {"dir": "DOWN", "keys": ["maxSeats"]}Direction (dir): The order of the sorting is set by the direction:
"UP": Sort results ascending"DOWN": Sort results descendingKeys: The keys field allows for sorting by multiple keys (i.e., columns), where each additional key resolves ties for the previous key.
Examples:
"keys": ["avg"]: sorts by a single key"keys": ["year", "avg"]: sorts by multiple keys. In this case, the average should be used to resolve ties for entries in the same yearRequirements:
You can use optional asterisks (*) in IS comparisons to match patterns.
For example, "IS": {"dept": "C*"} matches any department that starts with "C".
Because the asterisks can appear at the beginning and/or end, there are four possible forms:
inputstring: Matches inputstring exactly
*inputstring: Ends with inputstring
inputstring*: Starts with inputstring
*inputstring*: Contains inputstring
Asterisks in the middle are not allowed (for example, input*string).
| kind required | string Enum: "course_offerings" "facilities" The type of resource to query. |
| query required | object A query object that follows the DSL grammar defined in the EBNF. |
This query produces course offerings that have an average greater than 99.
{- "kind": "course_offerings",
- "query": {
- "WHERE": {
- "GT": {
- "avg": 99
}
}, - "OPTIONS": {
- "COLUMNS": [
- "dept",
- "avg"
]
}
}
}Example search results for the simple query on the PAIR dataset that selects sections with an average greater than 99.
[- {
- "dept": "cnps",
- "avg": 99.19
}, - {
- "dept": "math",
- "avg": 99.78
}, - {
- "dept": "math",
- "avg": 99.78
}
]Results are ordered by id ascending to ensure stable pagination.
| limit | integer [ 1 .. 5000 ] Default: 100 Maximum number of courses to return |
| offset | integer >= 0 Default: 0 Number of courses to skip |
{- "total": 2,
- "limit": 100,
- "offset": 0,
- "items": [
- {
- "id": "cpsc210",
- "title": "Software Construction",
- "dept": "Computer Science",
- "code": "210",
- "links": {
- "self": "/api/v1/courses/cpsc210",
- "sections": "/api/v1/courses/cpsc210/sections"
}
}, - {
- "id": "cpsc310",
- "title": "Introduction to Software Engineering",
- "dept": "Computer Science",
- "code": "310",
- "links": {
- "self": "/api/v1/courses/cpsc310",
- "sections": "/api/v1/courses/cpsc310/sections"
}
}
]
}{- "id": "cpsc310",
- "title": "Introduction to Software Engineering",
- "dept": "Computer Science",
- "code": "310",
- "links": {
- "self": "/api/v1/courses/cpsc310",
- "sections": "/api/v1/courses/cpsc310/sections"
}
}If the course already exists, the entire course is replaced; otherwise it is created.
| course required | string Example: cpsc310 Course identifier |
| title required | string The title of the course. |
| dept required | string The department that offers the course. |
| code required | string The course code identifier. |
{- "title": "Introduction to Software Engineering",
- "dept": "Computer Science",
- "code": "310"
}{- "id": "cpsc310",
- "title": "Introduction to Software Engineering",
- "dept": "Computer Science",
- "code": "310",
- "links": {
- "self": "/api/v1/courses/cpsc310",
- "sections": "/api/v1/courses/cpsc310/sections"
}
}The course and all of its sections are permanently removed. The response includes the course metadata and a count of sections that were removed.
| course required | string Example: cpsc310 Course identifier |
{- "id": "cpsc310",
- "title": "Introduction to Software Engineering",
- "dept": "Computer Science",
- "code": "310",
- "sections": 2
}Results are ordered by id ascending to ensure stable pagination.
| course required | string Example: cpsc310 Course identifier |
| limit | integer [ 1 .. 5000 ] Default: 100 Maximum number of sections to return |
| offset | integer >= 0 Default: 0 Number of sections to skip |
{- "total": 2,
- "limit": 100,
- "offset": 0,
- "items": [
- {
- "id": "21w201",
- "instructor": "holmes, reid",
- "year": 2021,
- "avg": 76.4,
- "pass": 167,
- "fail": 3,
- "audit": 1,
- "links": {
- "self": "/api/v1/courses/cpsc310/sections/21w201",
- "course": "/api/v1/courses/cpsc310"
}
}, - {
- "id": "21w202",
- "instructor": "bradley, nick",
- "year": 2021,
- "avg": 77.1,
- "pass": 172,
- "fail": 1,
- "audit": 0,
- "links": {
- "self": "/api/v1/courses/cpsc310/sections/21w202",
- "course": "/api/v1/courses/cpsc310"
}
}
]
}| course required | string Example: cpsc310 Course identifier |
| section required | string Example: 24w201 Section identifier |
{- "id": "21w201",
- "instructor": "holmes, reid",
- "year": 2021,
- "avg": 76.4,
- "pass": 167,
- "fail": 3,
- "audit": 1,
- "links": {
- "self": "/api/v1/courses/cpsc310/sections/21w201",
- "course": "/api/v1/courses/cpsc310"
}
}If the section already exists, the entire section is replaced; otherwise it is created.
| course required | string Example: cpsc310 Course identifier |
| section required | string Example: 24w201 Section identifier |
| instructor required | string The instructor's full name. |
| year required | integer [ 1900 .. 2099 ] The year in which the section was offered. |
| avg required | number [ 0 .. 100 ] The average grade of students enroled in the section. |
| pass required | integer >= 0 The number of students in the section who achieved a passing grade. |
| fail required | integer >= 0 The number of students in the section who did not achieve a passing grade. |
| audit required | integer >= 0 The number of students in the section who audited the course. |
{- "instructor": "holmes, reid",
- "year": 2021,
- "avg": 76.4,
- "pass": 167,
- "fail": 3,
- "audit": 1
}{- "id": "21w201",
- "instructor": "holmes, reid",
- "year": 2021,
- "avg": 76.4,
- "pass": 167,
- "fail": 3,
- "audit": 1,
- "links": {
- "self": "/api/v1/courses/cpsc310/sections/21w201",
- "course": "/api/v1/courses/cpsc310"
}
}The section is permanently removed and its data is returned.
| course required | string Example: cpsc310 Course identifier |
| section required | string Example: 24w201 Section identifier |
{- "id": "21w201",
- "instructor": "holmes, reid",
- "year": 2021,
- "avg": 76.4,
- "pass": 167,
- "fail": 3,
- "audit": 1
}Results are ordered by id ascending to ensure stable pagination.
| limit | integer [ 1 .. 5000 ] Default: 100 Maximum number of buildings to return |
| offset | integer >= 0 Default: 0 Number of buildings to skip |
{- "total": 2,
- "limit": 100,
- "offset": 0,
- "items": [
- {
- "id": "DMP",
- "name": "Hugh Dempster Pavilion",
- "address": "6245 Agronomy Road V6T 1Z4",
- "lat": 49.26125,
- "lon": -123.24807,
- "links": {
- "self": "/api/v2/buildings/DMP",
- "rooms": "/api/v2/buildings/DMP/rooms"
}
}, - {
- "id": "ORCH",
- "name": "Orchard Commons",
- "address": "6363 Agronomy Road",
- "lat": 49.26048,
- "lon": -123.25027,
- "links": {
- "self": "/api/v2/buildings/ORCH",
- "rooms": "/api/v2/buildings/ORCH/rooms"
}
}
]
}{- "id": "DMP",
- "name": "Hugh Dempster Pavilion",
- "address": "6245 Agronomy Road V6T 1Z4",
- "lat": 49.26125,
- "lon": -123.24807,
- "links": {
- "self": "/api/v2/buildings/DMP",
- "rooms": "/api/v2/buildings/DMP/rooms"
}
}If the building already exists, the entire building is replaced; otherwise it is created.
| building required | string Example: DMP Building identifier |
| name required | string The full name of the building. |
| address required | string The building address. |
| lat required | number The latitude of the building. |
| lon required | number The longitude of the building. |
{- "name": "Hugh Dempster Pavilion",
- "address": "6245 Agronomy Road V6T 1Z4",
- "lat": 49.26125,
- "lon": -123.24807
}{- "id": "DMP",
- "name": "Hugh Dempster Pavilion",
- "address": "6245 Agronomy Road V6T 1Z4",
- "lat": 49.26125,
- "lon": -123.24807,
- "links": {
- "self": "/api/v2/buildings/DMP",
- "rooms": "/api/v2/buildings/DMP/rooms"
}
}The building and all of its rooms are permanently removed. The response includes the building metadata and a count of rooms that were removed.
| building required | string Example: DMP Building identifier |
{- "id": "DMP",
- "name": "Hugh Dempster Pavilion",
- "address": "6245 Agronomy Road V6T 1Z4",
- "lat": 49.26125,
- "lon": -123.24807,
- "rooms": 82
}Results are ordered by id ascending to ensure stable pagination.
| building required | string Example: DMP Building identifier |
| limit | integer [ 1 .. 5000 ] Default: 100 Maximum number of rooms to return |
| offset | integer >= 0 Default: 0 Number of rooms to skip |
{- "total": 2,
- "limit": 100,
- "offset": 0,
- "items": [
- {
- "id": "DMP_101",
- "building": "DMP",
- "number": "101",
- "type": "Open Design General Purpose",
- "furniture": "Classroom-Movable Tables & Chairs",
- "seats": 40,
- "links": {
- "self": "/api/v2/buildings/DMP/rooms/DMP_101",
- "building": "/api/v2/buildings/DMP"
}
}, - {
- "id": "DMP_201",
- "building": "DMP",
- "number": "201",
- "type": "Small Group",
- "furniture": "Classroom-Movable Tables & Chairs",
- "seats": 25,
- "links": {
- "self": "/api/v2/buildings/DMP/rooms/DMP_201",
- "building": "/api/v2/buildings/DMP"
}
}
]
}| building required | string Example: DMP Building identifier |
| room required | string Example: DMP_101 Room identifier |
{- "id": "DMP_101",
- "building": "DMP",
- "number": "101",
- "type": "Open Design General Purpose",
- "furniture": "Classroom-Movable Tables & Chairs",
- "seats": 40,
- "links": {
- "self": "/api/v2/buildings/DMP/rooms/DMP_101",
- "building": "/api/v2/buildings/DMP"
}
}If the room already exists, the entire room is replaced; otherwise it is created.
| building required | string Example: DMP Building identifier |
| room required | string Example: DMP_101 Room identifier |
| building required | string The parent building shortname identifier. |
| number required | string The room number. Not always a number so represented as a string. |
| type required | string The room type. |
| furniture required | string The room furniture description. |
| href required | string Link to full room details. |
| seats required | integer >= 0 The number of seats in the room. |
{- "building": "DMP",
- "number": "101",
- "type": "Open Design General Purpose",
- "furniture": "Classroom-Movable Tables & Chairs",
- "seats": 40
}{- "id": "DMP_101",
- "building": "DMP",
- "number": "101",
- "type": "Open Design General Purpose",
- "furniture": "Classroom-Movable Tables & Chairs",
- "seats": 40,
- "links": {
- "self": "/api/v2/buildings/DMP/rooms/DMP_101",
- "building": "/api/v2/buildings/DMP"
}
}The room is permanently removed and its data is returned.
| building required | string Example: DMP Building identifier |
| room required | string Example: DMP_101 Room identifier |
{- "id": "DMP_101",
- "building": "DMP",
- "number": "101",
- "type": "Open Design General Purpose",
- "furniture": "Classroom-Movable Tables & Chairs",
- "seats": 40
}