{"openapi":"3.1.0","info":{"title":"Omniscol API","version":"1.0.0","description":"REST API for the Omniscol school-timetabling platform.\n\n**Authentication** — every request carries a JWT, sent as an `Authorization: Bearer <token>` header, an `authtoken` cookie, or (read-only routes) a `?auth=<token>` query parameter.\n\n**Roles** are ordered `student < teacher < admin`; each operation states the *minimal role* it requires (`public` = no role needed). Operations marked **Premium** require a Premium license."},"paths":{"/i18n/{lang}/{app}":{"get":{"tags":["I18n"],"summary":"Retrieve translations for a specific language and application","description":"`os_i18n_langapp_get` · **public**\n\nRetrieve translations for a specific language and application","operationId":"os_i18n_langapp_get","x-access":"all","parameters":[{"name":"lang","in":"path","required":true,"schema":{"type":"string","description":"Language code"},"description":"Language code"},{"name":"app","in":"path","required":true,"schema":{"type":"string","description":"Application name: portal, login, webapp","enum":["portal","login","webapp"]},"description":"Application name: portal, login, webapp"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/ims/oneroster/rostering/v1p2/{collection}/{id}/classes/{classid}/{nested}":{"get":{"tags":["Oneroster"],"summary":"OneRoster 1.2 Rostering (read-only) deep nested collection, e.g. /schools/{id}/classes/{classid}/students.","description":"`os_oneroster_rostering_class-nested_get` · **public**\n\nOneRoster 1.2 Rostering (read-only) deep nested collection, e.g. /schools/{id}/classes/{classid}/students.","operationId":"os_oneroster_rostering_class-nested_get","x-module":"oneroster","x-access":"all","parameters":[{"name":"collection","in":"path","required":true,"schema":{"type":"string","description":"OneRoster collection","enum":["orgs","schools","academicSessions","terms","gradingPeriods","courses","classes","enrollments","users","students","teachers","demographics"]},"description":"OneRoster collection"},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Parent (school) sourcedId"},"description":"Parent (school) sourcedId"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"Class sourcedId"},"description":"Class sourcedId"},{"name":"nested","in":"path","required":true,"schema":{"type":"string","description":"Nested collection under the class (students, teachers, enrollments)"},"description":"Nested collection under the class (students, teachers, enrollments)"},{"name":"filter","in":"query","required":false,"schema":{"type":"string","description":"OneRoster filter, e.g. role='student' (operators = != ~ > >= < <=, joined by a single AND or OR)"},"description":"OneRoster filter, e.g. role='student' (operators = != ~ > >= < <=, joined by a single AND or OR)"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Field to sort by"},"description":"Field to sort by"},{"name":"orderBy","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"description":"Sort direction (default asc)"},"description":"Sort direction (default asc)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Page size (default 100, max 10000)"},"description":"Page size (default 100, max 10000)"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","description":"Page offset (default 0)"},"description":"Page offset (default 0)"},{"name":"fields","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated field projection"},"description":"Comma-separated field projection"},{"name":"schoolYear","in":"query","required":false,"schema":{"type":"string","description":"School-year id to scope the data, or 'all' to span every year"},"description":"School-year id to scope the data, or 'all' to span every year"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","description":"OneRoster collection envelope keyed by the plural collection name, e.g. { \"users\": [ ... ] }. X-Total-Count and RFC 5988 Link headers carry pagination.","additionalProperties":{"type":"array","items":{"type":"object"}}}}}}}}},"/ims/oneroster/rostering/v1p2/{collection}/{id}/{nested}":{"get":{"tags":["Oneroster"],"summary":"OneRoster 1.2 Rostering (read-only) nested collection, e.g. /schools/{id}/classes, /classes/{id}/students, /users/{id}/classes, /terms/{id}/gradingPeriods.","description":"`os_oneroster_rostering_nested_get` · **public**\n\nOneRoster 1.2 Rostering (read-only) nested collection, e.g. /schools/{id}/classes, /classes/{id}/students, /users/{id}/classes, /terms/{id}/gradingPeriods.","operationId":"os_oneroster_rostering_nested_get","x-module":"oneroster","x-access":"all","parameters":[{"name":"collection","in":"path","required":true,"schema":{"type":"string","description":"OneRoster collection","enum":["orgs","schools","academicSessions","terms","gradingPeriods","courses","classes","enrollments","users","students","teachers","demographics"]},"description":"OneRoster collection"},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Parent resource sourcedId"},"description":"Parent resource sourcedId"},{"name":"nested","in":"path","required":true,"schema":{"type":"string","description":"Nested collection (classes, students, teachers, enrollments, courses, terms, gradingPeriods)"},"description":"Nested collection (classes, students, teachers, enrollments, courses, terms, gradingPeriods)"},{"name":"filter","in":"query","required":false,"schema":{"type":"string","description":"OneRoster filter, e.g. role='student' (operators = != ~ > >= < <=, joined by a single AND or OR)"},"description":"OneRoster filter, e.g. role='student' (operators = != ~ > >= < <=, joined by a single AND or OR)"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Field to sort by"},"description":"Field to sort by"},{"name":"orderBy","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"description":"Sort direction (default asc)"},"description":"Sort direction (default asc)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Page size (default 100, max 10000)"},"description":"Page size (default 100, max 10000)"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","description":"Page offset (default 0)"},"description":"Page offset (default 0)"},{"name":"fields","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated field projection"},"description":"Comma-separated field projection"},{"name":"schoolYear","in":"query","required":false,"schema":{"type":"string","description":"School-year id to scope the data, or 'all' to span every year"},"description":"School-year id to scope the data, or 'all' to span every year"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","description":"OneRoster collection envelope keyed by the plural collection name, e.g. { \"classes\": [ ... ] }. X-Total-Count and RFC 5988 Link headers carry pagination.","additionalProperties":{"type":"array","items":{"type":"object"}}}}}}}}},"/ims/oneroster/rostering/v1p2/{collection}/{id}":{"get":{"tags":["Oneroster"],"summary":"OneRoster 1.2 Rostering (read-only) single resource. Returns the envelope keyed by the singular name, e.g. { \"class\": { ... } }.","description":"`os_oneroster_rostering_item_get` · **public**\n\nOneRoster 1.2 Rostering (read-only) single resource. Returns the envelope keyed by the singular name, e.g. { \"class\": { ... } }.","operationId":"os_oneroster_rostering_item_get","x-module":"oneroster","x-access":"all","parameters":[{"name":"collection","in":"path","required":true,"schema":{"type":"string","description":"OneRoster collection","enum":["orgs","schools","academicSessions","terms","gradingPeriods","courses","classes","enrollments","users","students","teachers","demographics"]},"description":"OneRoster collection"},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Resource sourcedId"},"description":"Resource sourcedId"},{"name":"fields","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated field projection"},"description":"Comma-separated field projection"},{"name":"schoolYear","in":"query","required":false,"schema":{"type":"string","description":"School-year id to scope the data, or 'all' to span every year"},"description":"School-year id to scope the data, or 'all' to span every year"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","description":"OneRoster single-resource envelope keyed by the singular name, e.g. { \"class\": { ... } }.","additionalProperties":{"type":"object"}}}}}}}},"/ims/oneroster/rostering/v1p2/{collection}":{"get":{"tags":["Oneroster"],"summary":"OneRoster 1.2 Rostering (read-only) collection. Collections: orgs, schools, academicSessions, terms, gradingPeriods, courses, classes, enrollments, users, students, teachers, demographics. Returns the envelope keyed by the plural collection name, e.g. { \"classes\": [ ... ] }.","description":"`os_oneroster_rostering_collection_get` · **public**\n\nOneRoster 1.2 Rostering (read-only) collection. Collections: orgs, schools, academicSessions, terms, gradingPeriods, courses, classes, enrollments, users, students, teachers, demographics. Returns the envelope keyed by the plural collection name, e.g. { \"classes\": [ ... ] }.","operationId":"os_oneroster_rostering_collection_get","x-module":"oneroster","x-access":"all","parameters":[{"name":"collection","in":"path","required":true,"schema":{"type":"string","description":"OneRoster collection","enum":["orgs","schools","academicSessions","terms","gradingPeriods","courses","classes","enrollments","users","students","teachers","demographics"]},"description":"OneRoster collection"},{"name":"filter","in":"query","required":false,"schema":{"type":"string","description":"OneRoster filter, e.g. role='student' (operators = != ~ > >= < <=, joined by a single AND or OR)"},"description":"OneRoster filter, e.g. role='student' (operators = != ~ > >= < <=, joined by a single AND or OR)"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Field to sort by"},"description":"Field to sort by"},{"name":"orderBy","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"description":"Sort direction (default asc)"},"description":"Sort direction (default asc)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Page size (default 100, max 10000)"},"description":"Page size (default 100, max 10000)"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","description":"Page offset (default 0)"},"description":"Page offset (default 0)"},{"name":"fields","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated field projection"},"description":"Comma-separated field projection"},{"name":"schoolYear","in":"query","required":false,"schema":{"type":"string","description":"School-year id to scope the data, or 'all' to span every year"},"description":"School-year id to scope the data, or 'all' to span every year"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","description":"OneRoster collection envelope keyed by the plural collection name, e.g. { \"classes\": [ ... ] }. X-Total-Count and RFC 5988 Link headers carry pagination.","additionalProperties":{"type":"array","items":{"type":"object"}}}}}}}}},"/ims/oneroster/rostering/v1p2":{"get":{"tags":["Oneroster"],"summary":"OneRoster 1.2 Rostering (read-only) service discovery descriptor: supported collections and version.","description":"`os_oneroster_rostering_get` · **public**\n\nOneRoster 1.2 Rostering (read-only) service discovery descriptor: supported collections and version.","operationId":"os_oneroster_rostering_get","x-module":"oneroster","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","description":"Service descriptor: { service, version, profile, base, collections[] }.","properties":{"service":{"type":"string"},"version":{"type":"string"},"profile":{"type":"string"},"base":{"type":"string"},"collections":{"type":"array","items":{"type":"string"}}}}}}}}}},"/ims/oneroster/groups/v1p0/{collection}/{id}/{nested}":{"get":{"tags":["Oneroster"],"summary":"OneRoster Advanced Groups v1.0 (read-only) nested collection, e.g. /groups/{id}/memberships, /groups/{id}/users, /classes/{id}/groups, /users/{id}/groups.","description":"`os_oneroster_groups_nested_get` · **public**\n\nOneRoster Advanced Groups v1.0 (read-only) nested collection, e.g. /groups/{id}/memberships, /groups/{id}/users, /classes/{id}/groups, /users/{id}/groups.","operationId":"os_oneroster_groups_nested_get","x-module":"oneroster","x-access":"all","parameters":[{"name":"collection","in":"path","required":true,"schema":{"type":"string","description":"OneRoster Groups collection","enum":["groups","groupMemberships","groupAssociations"]},"description":"OneRoster Groups collection"},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Parent resource sourcedId"},"description":"Parent resource sourcedId"},{"name":"nested","in":"path","required":true,"schema":{"type":"string","description":"Nested collection (memberships, associations, users, groups)"},"description":"Nested collection (memberships, associations, users, groups)"},{"name":"filter","in":"query","required":false,"schema":{"type":"string","description":"OneRoster filter, e.g. groupType='class' (operators = != ~ > >= < <=, joined by a single AND or OR)"},"description":"OneRoster filter, e.g. groupType='class' (operators = != ~ > >= < <=, joined by a single AND or OR)"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Field to sort by"},"description":"Field to sort by"},{"name":"orderBy","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"description":"Sort direction (default asc)"},"description":"Sort direction (default asc)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Page size (default 100, max 10000)"},"description":"Page size (default 100, max 10000)"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","description":"Page offset (default 0)"},"description":"Page offset (default 0)"},{"name":"fields","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated field projection"},"description":"Comma-separated field projection"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","description":"OneRoster collection envelope keyed by the plural collection name, e.g. { \"groups\": [ ... ] }. X-Total-Count and RFC 5988 Link headers carry pagination.","additionalProperties":{"type":"array","items":{"type":"object"}}}}}}}}},"/ims/oneroster/groups/v1p0/{collection}/{id}":{"get":{"tags":["Oneroster"],"summary":"OneRoster Advanced Groups v1.0 (read-only) single resource. Returns the envelope keyed by the singular name, e.g. { \"group\": { ... } }.","description":"`os_oneroster_groups_item_get` · **public**\n\nOneRoster Advanced Groups v1.0 (read-only) single resource. Returns the envelope keyed by the singular name, e.g. { \"group\": { ... } }.","operationId":"os_oneroster_groups_item_get","x-module":"oneroster","x-access":"all","parameters":[{"name":"collection","in":"path","required":true,"schema":{"type":"string","description":"OneRoster Groups collection","enum":["groups","groupMemberships","groupAssociations"]},"description":"OneRoster Groups collection"},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Resource sourcedId"},"description":"Resource sourcedId"},{"name":"fields","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated field projection"},"description":"Comma-separated field projection"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","description":"OneRoster single-resource envelope keyed by the singular name, e.g. { \"group\": { ... } }.","additionalProperties":{"type":"object"}}}}}}}},"/ims/oneroster/groups/v1p0/{collection}":{"get":{"tags":["Oneroster"],"summary":"OneRoster Advanced Groups v1.0 (read-only) collection. Collections: groups, groupMemberships, groupAssociations. Returns the envelope keyed by the plural collection name, e.g. { \"groups\": [ ... ] }.","description":"`os_oneroster_groups_collection_get` · **public**\n\nOneRoster Advanced Groups v1.0 (read-only) collection. Collections: groups, groupMemberships, groupAssociations. Returns the envelope keyed by the plural collection name, e.g. { \"groups\": [ ... ] }.","operationId":"os_oneroster_groups_collection_get","x-module":"oneroster","x-access":"all","parameters":[{"name":"collection","in":"path","required":true,"schema":{"type":"string","description":"OneRoster Groups collection","enum":["groups","groupMemberships","groupAssociations"]},"description":"OneRoster Groups collection"},{"name":"filter","in":"query","required":false,"schema":{"type":"string","description":"OneRoster filter, e.g. groupType='class' (operators = != ~ > >= < <=, joined by a single AND or OR)"},"description":"OneRoster filter, e.g. groupType='class' (operators = != ~ > >= < <=, joined by a single AND or OR)"},{"name":"sort","in":"query","required":false,"schema":{"type":"string","description":"Field to sort by"},"description":"Field to sort by"},{"name":"orderBy","in":"query","required":false,"schema":{"type":"string","enum":["asc","desc"],"description":"Sort direction (default asc)"},"description":"Sort direction (default asc)"},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","description":"Page size (default 100, max 10000)"},"description":"Page size (default 100, max 10000)"},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","description":"Page offset (default 0)"},"description":"Page offset (default 0)"},{"name":"fields","in":"query","required":false,"schema":{"type":"string","description":"Comma-separated field projection"},"description":"Comma-separated field projection"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","description":"OneRoster collection envelope keyed by the plural collection name, e.g. { \"groups\": [ ... ] }. X-Total-Count and RFC 5988 Link headers carry pagination.","additionalProperties":{"type":"array","items":{"type":"object"}}}}}}}}},"/ims/oneroster/groups/v1p0":{"get":{"tags":["Oneroster"],"summary":"OneRoster Advanced Groups v1.0 (read-only) service discovery descriptor: supported collections and version.","description":"`os_oneroster_groups_get` · **public**\n\nOneRoster Advanced Groups v1.0 (read-only) service discovery descriptor: supported collections and version.","operationId":"os_oneroster_groups_get","x-module":"oneroster","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","description":"Service descriptor: { service, version, profile, base, collections[] }.","properties":{"service":{"type":"string"},"version":{"type":"string"},"profile":{"type":"string"},"base":{"type":"string"},"collections":{"type":"array","items":{"type":"string"}}}}}}}}}},"/api/home":{"get":{"tags":["Home"],"summary":"Retrieve configuration state/progression of the account","description":"`os_home_get` · minimal role **admin**\n\nRetrieve configuration state/progression of the account","operationId":"os_home_get","x-module":"home","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/schedules":{"get":{"tags":["Schedules"],"summary":"List the active (published) timetables only, with their structures and IDs. For ALL timetables including drafts, and their type (calendar/week) and status, use the timetables list instead. Use this to get the schedules currently in effect.","description":"`os_schedules_get` · minimal role **student**\n\nList the active (published) timetables only, with their structures and IDs. For ALL timetables including drafts, and their type (calendar/week) and status, use the timetables list instead. Use this to get the schedules currently in effect.","operationId":"os_schedules_get","x-module":"schedules","x-access":"student","parameters":[{"name":"school_year","in":"query","required":false,"schema":{"type":"string","description":"School year ID (by default: current school year)"},"description":"School year ID (by default: current school year)"},{"name":"with_useroptions","in":"query","required":false,"schema":{"type":"boolean","description":"Adding custom view options for current user to output"},"description":"Adding custom view options for current user to output"},{"name":"with_students","in":"query","required":false,"schema":{"type":"boolean","description":"Adding student list to output"},"description":"Adding student list to output"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"firstday":{"description":"First day of the week, 0 = Sunday, 1 = Monday","type":"integer","enum":[0,1],"default":1},"levels":{"type":"array","items":{"type":"string"}},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"school_years":{"description":"School years (academic years)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}},"students":{"description":"List of students with placements for the requested school year (if parameter with_students)","type":"object","additionalProperties":{"allOf":[{"$ref":"#/components/schemas/UserMinimal"},{"type":"object","properties":{"placements":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/Placement"},{"type":"object","properties":{"groups":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/PlacementGroup"},{"type":"object","properties":{"dates":{"description":"Computed date ranges parallel to weeks array","type":"array","items":{"type":"array","items":{"type":"string","format":"date"},"minItems":2,"maxItems":2}}}}]}}}}]}}}}]},"x-conditionalOnParameter":"with_students"},"teachers":{"description":"List of teachers","type":"object","additionalProperties":{"$ref":"#/components/schemas/TeacherMinimal"}},"timetables":{"description":"Active timetables on the requested school year","additionalProperties":{"$ref":"#/components/schemas/Timetable"}},"useroptions":{"$ref":"#/components/schemas/SchedulesOptions"},"school_year_id":{"description":"School year id","type":"string"}}}}}}}}},"/api/schedules/alterations/{school_year}":{"put":{"tags":["Schedules"],"summary":"Modify alterations for a given school year. Courses with position.day in YYYY-MM-DD format","description":"`os_schedules_put` · minimal role **admin**\n\nModify alterations for a given school year. Courses with position.day in YYYY-MM-DD format","operationId":"os_schedules_put","x-module":"schedules","x-access":"admin","parameters":[{"name":"school_year","in":"path","required":true,"schema":{"type":"string","description":"School year ID"},"description":"School year ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/Alterations"},{"type":"object","properties":{"buffer":{"description":"Unpositioned courses (no position.day) to store or merge into calendar timetables (backend auto-detects calendars from course.schedid)","type":"array","items":{"$ref":"#/components/schemas/LessonClass"}}}}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"revisions":{"description":"New _osrev values per timetable and course ID (for identity-based updates)","type":"object","additionalProperties":{"type":"object","additionalProperties":{"type":"string"}}},"merged":{"description":"Auto-merged courses per timetable (backend resolved conflicts)","type":"object","additionalProperties":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/LessonClass"}}},"ignored":{"description":"Courses that couldn't be stored (malformed, missing class, invalid _id, etc.)","type":"array","items":{"type":"object","properties":{"course":{"$ref":"#/components/schemas/LessonClass"},"reason":{"type":"string","enum":["no_target","invalid_id"]}}}}}}}}}}}},"/api/schedules/lessons/{datesrange}":{"get":{"tags":["Schedules"],"summary":"Retrieve lessons for a specific date range, by filter request","description":"`os_schedules_dates_get` · minimal role **student**\n\nRetrieve lessons for a specific date range, by filter request","operationId":"os_schedules_dates_get","x-module":"schedules","x-access":"student","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"with_timetables","in":"query","required":false,"schema":{"type":"boolean","description":"Add raw timetable structures used to compute all the courses/lessons (to have the details of classes, subjects, etc., by id)","x-mcp":{"default":true}},"description":"Add raw timetable structures used to compute all the courses/lessons (to have the details of classes, subjects, etc., by id)"},{"name":"with_all_teachers","in":"query","required":false,"schema":{"type":"boolean","description":"Add all teachers from timetable and admin (users)"},"description":"Add all teachers from timetable and admin (users)"},{"name":"with_teachers","in":"query","required":false,"schema":{"type":"boolean","description":"Add the list of teachers used on courses/lessons with all details"},"description":"Add the list of teachers used on courses/lessons with all details"},{"name":"with_hours","in":"query","required":false,"schema":{"type":"boolean","description":"Add start/end hours on each course/lesson","x-mcp":{"expose":"server-fixed","default":true}},"description":"Add start/end hours on each course/lesson"},{"name":"without_absences","in":"query","required":false,"schema":{"type":"boolean","description":"Ignore absences, do not consolidate absences/cancel courses"},"description":"Ignore absences, do not consolidate absences/cancel courses"},{"name":"with_absences","in":"query","required":false,"schema":{"type":"boolean","description":"Add all absences (raw data) during the selected period"},"description":"Add all absences (raw data) during the selected period"},{"name":"with_cancelcourses","in":"query","required":false,"schema":{"type":"boolean","description":"Do not remove canceled courses (= with all teachers being absent)"},"description":"Do not remove canceled courses (= with all teachers being absent)"},{"name":"with_studentcancelcourses","in":"query","required":false,"schema":{"type":"boolean","description":"Keep only canceled courses of students with absence"},"description":"Keep only canceled courses of students with absence"},{"name":"with_removedcourses","in":"query","required":false,"schema":{"type":"boolean","description":"Exclusive with with_cancelcourses"},"description":"Exclusive with with_cancelcourses"},{"name":"without_teacher_consolidation","in":"query","required":false,"schema":{"type":"boolean","description":"Do not remove absent teachers from 'teachers' key in concerned courses"},"description":"Do not remove absent teachers from 'teachers' key in concerned courses"},{"name":"without_holidays","in":"query","required":false,"schema":{"type":"boolean","description":"Do not inject holidays"},"description":"Do not inject holidays"},{"name":"with_students","in":"query","required":false,"schema":{"type":"boolean","description":"Add list of students from admin (users)"},"description":"Add list of students from admin (users)"},{"name":"with_events","in":"query","required":false,"schema":{"type":"boolean","description":"Add events","x-mcp":{"default":true}},"description":"Add events"},{"name":"timetables_restrict","in":"query","required":false,"schema":{"type":"string","description":"Restrict extraction to these timetable IDs (string, CSV, or array)"},"description":"Restrict extraction to these timetable IDs (string, CSV, or array)"},{"name":"timetables_exclude","in":"query","required":false,"schema":{"type":"string","description":"Exclude these timetable IDs from extraction (string, CSV, or array)"},"description":"Exclude these timetable IDs from extraction (string, CSV, or array)"},{"name":"limit","in":"query","required":false,"schema":{"description":"Limit the number of lessons returned for each filter requested","type":"integer","minimum":1},"description":"Limit the number of lessons returned for each filter requested"},{"name":"filter","in":"query","required":false,"schema":{"description":"Filter of what is to be queried among classes, teachers, groups, classrooms, groups, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students, events, awaitingclassroom, awaitingteacher. Filters can be cumulative. For each filter, an array of id or object to filter according to a field. It also supports wildcards. If filter is empty, { \"classes\": \"*\" } will be the applied default behavior. With $where, dot-path fields like 'sites.name' are supported; for classes this resolves through class.site/class.sites IDs to timetable sites.","type":"object","properties":{"events":{"type":"string","enum":["*"]},"awaitingclassroom":{"description":"Admin-only. Returns lessons positioned but missing a classroom (excluding explicit no-room locks and remote/self_study modalities).","type":"string","enum":["*"]},"awaitingteacher":{"description":"Admin-only. Returns lessons positioned but missing a teacher (excluding explicit no-teacher locks; absences/substitutions handled via dedicated absences endpoints, not surfaced here).","type":"string","enum":["*"]},"classes":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"teachers":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"groups":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"classrooms":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"groupswithclasses":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"resources":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"subjects":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"types":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"teachersbyclasses":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"teachersbysubjects":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"students":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]}},"x-mcp":{"expose":"required"}},"description":"Filter of what is to be queried among classes, teachers, groups, classrooms, groups, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students, events, awaitingclassroom, awaitingteacher. Filters can be cumulative. For each filter, an array of id or object to filter according to a field. It also supports wildcards. If filter is empty, { \"classes\": \"*\" } will be the applied default behavior. With $where, dot-path fields like 'sites.name' are supported; for classes this resolves through class.site/class.sites IDs to timetable sites.","examples":{"classes":{"value":"{\"classes\":[\"6a\",\"6b\",\"6c\"]}","summary":"classes of ID 6a, 6b and 6c"},"teachers":{"value":"{\"teachers\":[\"robert-bresson\",{\"first_name\":\"Albert\"}],\"classrooms\":[\"*\"]}","summary":"teacher of ID robert-bresson, and all teachers with first name 'Albert' and all classrooms"},"classroomsAndSubjects":{"value":"{\"classrooms\":[\"site1:*\"],\"subjects\":\"*\"}","summary":"all classrooms from site ID site1, and all subjects"},"studentByEmail":{"value":"{\"students\":[{\"email\":\"kevin@gmail.com\"}]}","summary":"the student(s) with email kevin@gmail.com"},"classroomsFiltered":{"value":"{\"classrooms\":[{\"$where\":{\"capacity\":{\"$gte\":20}}}]}","summary":"all classrooms with capacity >= 20"},"classesBySiteNameWhere":{"value":"{\"classes\":[{\"$where\":{\"capacity\":{\"$gt\":30},\"sites.name\":{\"$regex\":\"avignon\"}}}]}","summary":"all classes filtered with $where: capacity > 30 and linked site name matches 'avignon'"},"virtualTeachers":{"value":"{\"teachers\":[{\"$where\":{\"virtual_name\":{\"$exists\":true}}}]}","summary":"all virtual teachers (not yet hired)"},"awaitingClassroom":{"value":"{\"awaitingclassroom\":\"*\"}","summary":"all lessons missing a classroom"},"awaitingTeacher":{"value":"{\"awaitingteacher\":\"*\"}","summary":"all lessons missing a teacher"}}},{"name":"with_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"filter":{"description":"The parsed filter, as is","type":"object"},"computedfilter":{"description":"The extended filter with all IDs (wildcard replaced, found objects with matching fields, etc.)","type":"object"},"query":{"description":"The query sent on the URL (debug purpose)","type":"string"},"sched_ids":{"description":"IDs of the timetables of which lessons were extracted","type":"array","items":{"type":"string"}},"schedules":{"description":"All the filtered lessons for all the filters, sorted by type of filter (classes, teachers, subjects, ...) then value (id of class, teacher, subject, ...)","type":"object","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students|awaitingclassroom|awaitingteacher)$":{"description":"All filtered lesson of given type, for each requested id value","type":"object","additionalProperties":{"description":"The list of lessons (with exact date/period + start/end if with_hours parameter)","type":"object","properties":{"courses":{"type":"array","items":{"$ref":"#/components/schemas/LessonSchedule"}}}}}},"examples":[{"classes":{"3a":{"courses":[{"duration":2,"position":{"day":"2022-09-01","period":0,"start":"8:15","end":"9:10"},"subject":"maths","teachers":["john-doe"],"schedid":"3","class":"3a"}]}}},{"teachers":{"john-doe":{"courses":[{"duration":2,"position":{"day":"2022-09-01","period":0,"start":"8:15","end":"9:10"},"subject":"maths","teachers":["john-doe"],"schedid":"3","class":"3a"}]}}}]},"events":{"description":"Events, as in a regular calendar, are not lessons, yet it is something happening in the school, outside the regular grid, such as a council, a parent-teacher meeting, etc.","type":"object","additionalProperties":{"$ref":"#/components/schemas/Event"},"x-conditionalOnParameter":"with_events"},"timetables":{"description":"Timetables active on date range","type":"object","additionalProperties":{"$ref":"#/components/schemas/Timetable"},"x-conditionalOnParameter":"with_timetables"},"teachers":{"description":"List of teachers","type":"object","additionalProperties":{"$ref":"#/components/schemas/TeacherMinimal"},"x-conditionalOnParameter":["with_all_teachers","with_teachers"]},"students":{"description":"List of students with placements organized by date","type":"object","additionalProperties":{"allOf":[{"$ref":"#/components/schemas/UserMinimal"},{"type":"object","properties":{"placements":{"description":"Student placements organized by date (YYYY-MM-DD)","type":"object","additionalProperties":{"type":"object","properties":{"classes":{"description":"List of class IDs","type":"array","items":{"type":"string"}},"groups":{"description":"List of group IDs","type":"array","items":{"type":"string"}}}}}}}]},"x-conditionalOnParameter":"with_students"},"entities":{"description":"Entity details grouped by entity type, then by entity ID","type":"object","x-conditionalOnParameter":"with_entities","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"middle_name":{"type":"string"},"virtual_name":{"type":"string"}}}}}}}}}}}}}},"/api/schedules/lessons/{datesrange}/{entity}":{"get":{"tags":["Schedules"],"summary":"Retrieve lessons for all {entity} in a specific date range. Entity must be one of: classes, teachers, groups, classrooms, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students","description":"`os_schedules_dates_entities_get` · minimal role **admin**\n\nRetrieve lessons for all {entity} in a specific date range. Entity must be one of: classes, teachers, groups, classrooms, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students","operationId":"os_schedules_dates_entities_get","x-module":"schedules","x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","enum":["classes","teachers","classrooms","subjects","resources","types","groups","students","groupswithclasses","teachersbyclasses","teachersbysubjects"],"description":"Type of entity to retrieve lessons for"},"description":"Type of entity to retrieve lessons for"},{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"with_hours","in":"query","required":false,"schema":{"type":"boolean","description":"Add start/end hours on each course/lesson","x-mcp":{"expose":"server-fixed","default":true}},"description":"Add start/end hours on each course/lesson"},{"name":"with_timetables","in":"query","required":false,"schema":{"type":"boolean","description":"Add raw timetable structures used to compute all the courses/lessons","x-mcp":{"default":true}},"description":"Add raw timetable structures used to compute all the courses/lessons"},{"name":"with_events","in":"query","required":false,"schema":{"type":"boolean","description":"Add events","x-mcp":{"default":true}},"description":"Add events"},{"name":"with_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"schedules":{"description":"All the filtered lessons for the requested entity type","type":"object","additionalProperties":{"description":"The list of lessons for each entity ID","type":"object","properties":{"courses":{"type":"array","items":{"$ref":"#/components/schemas/LessonSchedule"}}}}},"events":{"description":"Events in the date range","type":"object","additionalProperties":{"$ref":"#/components/schemas/Event"},"x-conditionalOnParameter":"with_events"},"timetables":{"description":"Timetables active on date range","type":"object","additionalProperties":{"$ref":"#/components/schemas/Timetable"},"x-conditionalOnParameter":"with_timetables"},"entities":{"description":"Entity details grouped by entity type, then by entity ID","type":"object","x-conditionalOnParameter":"with_entities","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"middle_name":{"type":"string"},"virtual_name":{"type":"string"}}}}}}}}}}}}}},"/api/schedules/lessons/{datesrange}/{entity}/{entityId}":{"get":{"tags":["Schedules"],"summary":"Retrieve lessons for a specific {entity} in a date range. Entity must be one of: classes, teachers, groups, classrooms, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students","description":"`os_schedules_dates_entity_get` · minimal role **admin**\n\nRetrieve lessons for a specific {entity} in a date range. Entity must be one of: classes, teachers, groups, classrooms, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students","operationId":"os_schedules_dates_entity_get","x-module":"schedules","x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","enum":["classes","teachers","classrooms","subjects","resources","types","groups","students","groupswithclasses","teachersbyclasses","teachersbysubjects"],"description":"Type of entity to retrieve lessons for"},"description":"Type of entity to retrieve lessons for"},{"name":"entityId","in":"path","required":true,"schema":{"type":"string","description":"ID of the specific entity"},"description":"ID of the specific entity"},{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"with_timetables","in":"query","required":false,"schema":{"type":"boolean","description":"Add raw timetable structures used to compute all the courses/lessons","x-mcp":{"default":true}},"description":"Add raw timetable structures used to compute all the courses/lessons"},{"name":"with_events","in":"query","required":false,"schema":{"type":"boolean","description":"Add events","x-mcp":{"default":true}},"description":"Add events"},{"name":"with_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"schedule":{"description":"The lessons for the specific entity","type":"object","properties":{"courses":{"type":"array","items":{"$ref":"#/components/schemas/LessonSchedule"}}}},"events":{"description":"Events in the date range","type":"object","additionalProperties":{"$ref":"#/components/schemas/Event"},"x-conditionalOnParameter":"with_events"},"timetables":{"description":"Timetables active on date range","type":"object","additionalProperties":{"$ref":"#/components/schemas/Timetable"},"x-conditionalOnParameter":"with_timetables"},"entities":{"description":"Entity details grouped by entity type, then by entity ID","type":"object","x-conditionalOnParameter":"with_entities","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"middle_name":{"type":"string"},"virtual_name":{"type":"string"}}}}}}}}}}}}}},"/api/schedules/entities/{entity}/{datesrange}":{"get":{"tags":["Schedules"],"summary":"Retrieve all active entities of a specific type in a date range. Entity must be one of: classes, teachers, groups, classrooms, resources, subjects, sites, students, school_years.","description":"`os_schedules_entities_dates_get` · minimal role **admin**\n\nRetrieve all active entities of a specific type in a date range. Entity must be one of: classes, teachers, groups, classrooms, resources, subjects, sites, students, school_years.","operationId":"os_schedules_entities_dates_get","x-module":"schedules","x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","enum":["classes","teachers","classrooms","subjects","resources","groups","sites","students","school_years"],"description":"Type of entity to list"},"description":"Type of entity to list"},{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"sched_ids":{"description":"IDs of the timetables of which entities were extracted","type":"array","items":{"type":"string"}},"date_start":{"description":"Start date","type":"string","format":"date"},"date_end":{"description":"End date","type":"string","format":"date"},"school_years":{"description":"School year entities","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"School year name"},"date_start":{"type":"string","description":"Start date"},"date_end":{"type":"string","description":"End date"},"holidays":{"type":"array","description":"Holidays list","items":{"$ref":"#/components/schemas/Holiday"}}}}},"teachers":{"description":"User entities with personal details","type":"object","additionalProperties":{"$ref":"#/components/schemas/UserMinimal"}},"students":{"description":"User entities with personal details","type":"object","additionalProperties":{"$ref":"#/components/schemas/UserMinimal"}},"classes":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"groups":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"subjects":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"sites":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"classrooms":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"resources":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}}}}}}}}}},"/api/schedules/entities/{entity}":{"get":{"tags":["Schedules"],"summary":"Retrieve all active entities of a specific type for the current school year. Entity must be one of: classes, teachers, groups, classrooms, resources, subjects, sites, students, school_years. If school_years, return all school years (academic years)","description":"`os_schedules_entities_get` · minimal role **admin**\n\nRetrieve all active entities of a specific type for the current school year. Entity must be one of: classes, teachers, groups, classrooms, resources, subjects, sites, students, school_years. If school_years, return all school years (academic years)","operationId":"os_schedules_entities_get","x-module":"schedules","x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","enum":["classes","teachers","classrooms","subjects","resources","groups","sites","students","school_years"],"description":"Type of entity to list"},"description":"Type of entity to list"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"sched_ids":{"description":"IDs of the timetables of which entities were extracted","type":"array","items":{"type":"string"}},"date_start":{"description":"Start date","type":"string","format":"date"},"date_end":{"description":"End date","type":"string","format":"date"},"school_years":{"description":"School year entities","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"School year name"},"date_start":{"type":"string","description":"Start date"},"date_end":{"type":"string","description":"End date"},"holidays":{"type":"array","description":"Holidays list","items":{"$ref":"#/components/schemas/Holiday"}}}}},"teachers":{"description":"User entities with personal details","type":"object","additionalProperties":{"$ref":"#/components/schemas/UserMinimal"}},"students":{"description":"User entities with personal details","type":"object","additionalProperties":{"$ref":"#/components/schemas/UserMinimal"}},"classes":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"groups":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"subjects":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"sites":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"classrooms":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}},"resources":{"description":"Standard entities (classes, groups, subjects, sites, classrooms, resources)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Entity name"},"type":{"type":"string","description":"Entity type"},"level":{"type":"string","description":"Entity level"},"code":{"type":"string","description":"Entity code"},"comment":{"type":"string","description":"Entity comment"},"description":{"type":"string","description":"Entity description"},"color":{"type":"string","description":"Entity color"},"class":{"type":"string","description":"Parent class (for groups)"},"site":{"type":"string","description":"Parent site (for classrooms/resources)"}}}}}}}}}}}},"/api/schedules/entities":{"get":{"tags":["Schedules"],"summary":"Retrieve all active entities of all types for the current school year. Entity will be classes, teachers, students, groups, sites, classrooms, resources, subjects, school_years","description":"`os_schedules_entities_all_get` · minimal role **admin**\n\nRetrieve all active entities of all types for the current school year. Entity will be classes, teachers, students, groups, sites, classrooms, resources, subjects, school_years","operationId":"os_schedules_entities_all_get","x-module":"schedules","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/schedules/timetables/{datesrange}":{"get":{"tags":["Schedules"],"summary":"Retrieve complete timetables for a specific date range","description":"`os_schedules_dates-timetable_get` · minimal role **teacher**\n\nRetrieve complete timetables for a specific date range","operationId":"os_schedules_dates-timetable_get","x-module":"schedules","x-access":"teacher","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"with_buffer","in":"query","required":false,"schema":{"description":"Also sends the buffer of courses with no position","type":"boolean"},"description":"Also sends the buffer of courses with no position"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absences":{"description":"Absences of teachers","type":"object","additionalProperties":{"description":"Absences for a specific teacher (by ID of teacher, then by index)","type":"object","additionalProperties":{"$ref":"#/components/schemas/AbsenceTeacher"}}},"alterations":{"$ref":"#/components/schemas/Alterations"},"buffer":{"description":"Buffer of lessons not yet scheduled (temporary storage, without position)","type":"array","items":{"$ref":"#/components/schemas/LessonAlteration"},"x-conditionalOnParameter":"with_buffer"},"timetables":{"description":"Timetables active on the date range, by ID","type":"object","additionalProperties":{"$ref":"#/components/schemas/Timetable"}}}}}}}}}},"/api/schedules/events":{"post":{"tags":["Schedules"],"summary":"Create a new event in the schedule","description":"`os_schedules_events_post` · minimal role **admin** · **Premium**\n\nCreate a new event in the schedule","operationId":"os_schedules_events_post","x-module":"schedules","x-premium":true,"x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"events":{"type":"array","items":{"$ref":"#/components/schemas/Event"}}},"required":["events"]},{"type":"object","properties":{"event":{"$ref":"#/components/schemas/Event"}},"required":["event"]}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"events":{"description":"Created events keyed by their canonical storage ID in doc.events. New events use an opaque generated identifier; historical keys such as eventXX can still exist on older data. In batch mode, valid items are stored even if some other items are ignored.","type":"object","additionalProperties":{"$ref":"#/components/schemas/Event"}},"ignored":{"description":"Batch items that were ignored because they were invalid.","type":"array","items":{"type":"object","properties":{"message":{"type":"string","description":"Validation error for the ignored item."},"event":{"$ref":"#/components/schemas/Event"}}}}}}}}}}}},"/api/schedules/events/{eventid}":{"put":{"tags":["Schedules"],"summary":"Update an existing event in the schedule (full replacement)","description":"`os_schedules_events_put` · minimal role **admin** · **Premium**\n\nUpdate an existing event in the schedule (full replacement)","operationId":"os_schedules_events_put","x-module":"schedules","x-premium":true,"x-access":"admin","parameters":[{"name":"eventid","in":"path","required":true,"schema":{"type":"string","description":"Event ID"},"description":"Event ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"$ref":"#/components/schemas/Event"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"events":{"description":"Updated event keyed by its canonical storage ID in doc.events.","type":"object","additionalProperties":{"$ref":"#/components/schemas/Event"}}}}}}}}},"patch":{"tags":["Schedules"],"summary":"Partially update an event (merge modified fields onto current version). Set field to null to delete it.","description":"`os_schedules_events_patch` · minimal role **admin** · **Premium**\n\nPartially update an event (merge modified fields onto current version). Set field to null to delete it.","operationId":"os_schedules_events_patch","x-module":"schedules","x-premium":true,"x-access":"admin","parameters":[{"name":"eventid","in":"path","required":true,"schema":{"type":"string","description":"Event ID"},"description":"Event ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"event":{"description":"Partial event patch. Send only changed fields. _arrayops is optional metadata used to replay add/remove diffs on array fields when the client sends a stale _osrev; it is never stored on the event.","type":"object","properties":{"title":{"description":"Title of the event (to be displayed)","type":"string"},"start":{"description":"Start of the event (format YYYYMMDDTHHmmSS)","type":"string","pattern":"^\\d{8}T\\d{6}$"},"end":{"description":"End of the event (format YYYYMMDDTHHmmSS)","type":"string","pattern":"^\\d{8}T\\d{6}$"},"rrule":{"$ref":"#/components/schemas/Rrule"},"attendees":{"title":"Users/entities to attend the event","description":"Users/entities to attend the event. It can be a user, a class, a group, a custom name or the whole school (everybody) or anyone who wants to (anyone)","type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["user"]},"id":{"type":"string"},"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"},"roles":{"type":"array","items":{"type":"string"}}},"required":["type","id","first_name","middle_name","last_name"]},{"type":"object","properties":{"type":{"type":"string","enum":["class"]},"id":{"type":"string"},"name":{"type":"string"}},"required":["type","id","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["group"]},"id":{"type":"string"},"name":{"type":"string"},"code":{"type":"string"}},"required":["type","id","name","code"]},{"type":"object","properties":{"type":{"type":"string","enum":["custom"]},"name":{"type":"string"}},"required":["type","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["everybody","anyone"]}},"required":["type"]}]}},"location":{"description":"The location(s) of the event (either a classroom or a custom label)","type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["classroom"]},"name":{"type":"string"},"id":{"type":"string"},"sitename":{"type":"string"}},"required":["type","name","id"]},{"type":"object","properties":{"type":{"type":"string","enum":["custom"]},"name":{"type":"string"}},"required":["type","name"]}]}},"resources":{"description":"The resources to be used/reserved for the event","type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["resource"]},"id":{"type":"string"},"name":{"type":"string"},"sitename":{"type":"string"}},"required":["type","id"]},{"type":"object","properties":{"type":{"type":"string","enum":["custom"]},"name":{"type":"string"}},"required":["type","name"]}]}},"videolink":{"description":"Video link to remotely attend to the event","type":"string"},"memos":{"description":"Comments on the event","type":"array","items":{"$ref":"#/components/schemas/Memo"}},"color":{"description":"Color of the event (hexadecimal without #, e.g. '1bc5b3')","type":"string","pattern":"^[0-9A-Fa-f]{6}$"},"_osrev":{"description":"Optimistic locking revision counter for the event","type":"string"},"_arrayops":{"type":"object","description":"Optional add/remove diffs for array fields. Keys are the same array fields as above, typically attendees, location, resources or memos. Each value is an object with optional add/remove arrays using the same item format as the corresponding field above.","additionalProperties":{"type":"object","properties":{"add":{"type":"array","items":{}},"remove":{"type":"array","items":{}}}}}}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"events":{"description":"Updated event keyed by its canonical storage ID in doc.events.","type":"object","additionalProperties":{"$ref":"#/components/schemas/Event"}},"merged":{"type":"boolean","description":"True when the client sent a stale _osrev and the backend merged onto the latest version."}}}}}}}},"delete":{"tags":["Schedules"],"summary":"Delete an event from the schedule","description":"`os_schedules_events_delete` · minimal role **admin** · **Premium**\n\nDelete an event from the schedule","operationId":"os_schedules_events_delete","x-module":"schedules","x-premium":true,"x-access":"admin","parameters":[{"name":"eventid","in":"path","required":true,"schema":{"type":"string","description":"Event ID"},"description":"Event ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/schedules/options":{"put":{"tags":["Schedules"],"summary":"Update user's schedule module configuration options","description":"`os_schedules_options_put` · minimal role **admin**\n\nUpdate user's schedule module configuration options","operationId":"os_schedules_options_put","x-module":"schedules","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"restore":{"type":"boolean","description":"Restore the schedules when going back to the module screen"},"customs":{"type":"array","description":"Filters saved as bundles to display","items":{"type":"object","properties":{"name":{"type":"string","description":"Name of the saved bundle"},"schedules":{"type":"array","description":"Saved schedule filters for the bundle","items":{"type":"object","additionalProperties":true}}}}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/schedules/occupancy/{datesrange}":{"get":{"tags":["Schedules"],"summary":"Retrieve occupied timeslots in a date range using an explicit filter. Supports one or multiple entity types in filter (same structure as /schedules/lessons/:datesrange, including $where).","description":"`os_schedules_occupancy_get` · minimal role **student**\n\nRetrieve occupied timeslots in a date range using an explicit filter. Supports one or multiple entity types in filter (same structure as /schedules/lessons/:datesrange, including $where).","operationId":"os_schedules_occupancy_get","x-module":"schedules","x-access":"student","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"filter","in":"query","required":false,"schema":{"description":"Filter of what is to be queried among classes, teachers, groups, classrooms, groups, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students, events, awaitingclassroom, awaitingteacher. Filters can be cumulative. For each filter, an array of id or object to filter according to a field. It also supports wildcards. If filter is empty, { \"classes\": \"*\" } will be the applied default behavior. With $where, dot-path fields like 'sites.name' are supported; for classes this resolves through class.site/class.sites IDs to timetable sites.","type":"object","properties":{"events":{"type":"string","enum":["*"]},"awaitingclassroom":{"description":"Admin-only. Returns lessons positioned but missing a classroom (excluding explicit no-room locks and remote/self_study modalities).","type":"string","enum":["*"]},"awaitingteacher":{"description":"Admin-only. Returns lessons positioned but missing a teacher (excluding explicit no-teacher locks; absences/substitutions handled via dedicated absences endpoints, not surfaced here).","type":"string","enum":["*"]},"classes":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"teachers":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"groups":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"classrooms":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"groupswithclasses":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"resources":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"subjects":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"types":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"teachersbyclasses":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"teachersbysubjects":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"students":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]}},"x-mcp":{"expose":"required"}},"description":"Filter of what is to be queried among classes, teachers, groups, classrooms, groups, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students, events, awaitingclassroom, awaitingteacher. Filters can be cumulative. For each filter, an array of id or object to filter according to a field. It also supports wildcards. If filter is empty, { \"classes\": \"*\" } will be the applied default behavior. With $where, dot-path fields like 'sites.name' are supported; for classes this resolves through class.site/class.sites IDs to timetable sites.","examples":{"classes":{"value":"{\"classes\":[\"6a\",\"6b\",\"6c\"]}","summary":"classes of ID 6a, 6b and 6c"},"teachers":{"value":"{\"teachers\":[\"robert-bresson\",{\"first_name\":\"Albert\"}],\"classrooms\":[\"*\"]}","summary":"teacher of ID robert-bresson, and all teachers with first name 'Albert' and all classrooms"},"classroomsAndSubjects":{"value":"{\"classrooms\":[\"site1:*\"],\"subjects\":\"*\"}","summary":"all classrooms from site ID site1, and all subjects"},"studentByEmail":{"value":"{\"students\":[{\"email\":\"kevin@gmail.com\"}]}","summary":"the student(s) with email kevin@gmail.com"},"classroomsFiltered":{"value":"{\"classrooms\":[{\"$where\":{\"capacity\":{\"$gte\":20}}}]}","summary":"all classrooms with capacity >= 20"},"classesBySiteNameWhere":{"value":"{\"classes\":[{\"$where\":{\"capacity\":{\"$gt\":30},\"sites.name\":{\"$regex\":\"avignon\"}}}]}","summary":"all classes filtered with $where: capacity > 30 and linked site name matches 'avignon'"},"virtualTeachers":{"value":"{\"teachers\":[{\"$where\":{\"virtual_name\":{\"$exists\":true}}}]}","summary":"all virtual teachers (not yet hired)"},"awaitingClassroom":{"value":"{\"awaitingclassroom\":\"*\"}","summary":"all lessons missing a classroom"},"awaitingTeacher":{"value":"{\"awaitingteacher\":\"*\"}","summary":"all lessons missing a teacher"}}},{"name":"with_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"occupancy":{"description":"Timeslots grouped by entity type, then by entity ID","type":"object","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","example":"2025-09-02"},"start":{"type":"string","example":"09:00"},"end":{"type":"string","example":"11:00"},"time":{"type":"integer","example":120}}}}}}},"entities":{"description":"Entity details grouped by entity type, then by entity ID","type":"object","x-conditionalOnParameter":"with_entities","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"middle_name":{"type":"string"},"virtual_name":{"type":"string"}}}}}}}}}}}}}},"/api/schedules/occupancy/{datesrange}/{entity}":{"get":{"tags":["Schedules"],"summary":"Retrieve occupied timeslots for one entity type in a date range. This route is entity-scoped and builds an ad-hoc wildcard filter internally.","description":"`os_schedules_occupancy-entities_get` · minimal role **student**\n\nRetrieve occupied timeslots for one entity type in a date range. This route is entity-scoped and builds an ad-hoc wildcard filter internally.","operationId":"os_schedules_occupancy-entities_get","x-module":"schedules","x-access":"student","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"entity","in":"path","required":true,"schema":{"type":"string","enum":["classes","teachers","classrooms","subjects","resources","types","groups","students","groupswithclasses","teachersbyclasses","teachersbysubjects"],"description":"Entity type for which occupancy/availability timeslots are requested"},"description":"Entity type for which occupancy/availability timeslots are requested"},{"name":"with_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"occupancy":{"description":"Timeslots grouped by entity type, then by entity ID","type":"object","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","example":"2025-09-02"},"start":{"type":"string","example":"09:00"},"end":{"type":"string","example":"11:00"},"time":{"type":"integer","example":120}}}}}}},"entities":{"description":"Entity details grouped by entity type, then by entity ID","type":"object","x-conditionalOnParameter":"with_entities","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"middle_name":{"type":"string"},"virtual_name":{"type":"string"}}}}}}}}}}}}}},"/api/schedules/occupancy/{datesrange}/{entity}/{entityId}":{"get":{"tags":["Schedules"],"summary":"Retrieve occupied timeslots for one explicit entity ID.","description":"`os_schedules_occupancy-entity_get` · minimal role **student**\n\nRetrieve occupied timeslots for one explicit entity ID.","operationId":"os_schedules_occupancy-entity_get","x-module":"schedules","x-access":"student","parameters":[{"name":"entityId","in":"path","required":true,"schema":{"type":"string","description":"Explicit entity identifier to resolve (e.g. site1:room1)"},"description":"Explicit entity identifier to resolve (e.g. site1:room1)"},{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"entity","in":"path","required":true,"schema":{"type":"string","enum":["classes","teachers","classrooms","subjects","resources","types","groups","students","groupswithclasses","teachersbyclasses","teachersbysubjects"],"description":"Entity type for which occupancy/availability timeslots are requested"},"description":"Entity type for which occupancy/availability timeslots are requested"},{"name":"with_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"occupancy":{"description":"Timeslots grouped by entity type, then by entity ID","type":"object","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","example":"2025-09-02"},"start":{"type":"string","example":"09:00"},"end":{"type":"string","example":"11:00"},"time":{"type":"integer","example":120}}}}}}},"entities":{"description":"Entity details grouped by entity type, then by entity ID","type":"object","x-conditionalOnParameter":"with_entities","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"middle_name":{"type":"string"},"virtual_name":{"type":"string"}}}}}}}}}}}}}},"/api/schedules/availability/{datesrange}":{"get":{"tags":["Schedules"],"summary":"Retrieve available timeslots in a date range using an explicit filter. Availability is computed from occupied slots plus additional unavailabilities (entity absences for teachers/classes/students, and mandatory wishes including site wishes when applicable), then clipped by opening_hours or timetable bounds.","description":"`os_schedules_availability_get` · minimal role **student**\n\nRetrieve available timeslots in a date range using an explicit filter. Availability is computed from occupied slots plus additional unavailabilities (entity absences for teachers/classes/students, and mandatory wishes including site wishes when applicable), then clipped by opening_hours or timetable bounds.","operationId":"os_schedules_availability_get","x-module":"schedules","x-access":"student","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"filter","in":"query","required":false,"schema":{"description":"Filter of what is to be queried among classes, teachers, groups, classrooms, groups, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students, events, awaitingclassroom, awaitingteacher. Filters can be cumulative. For each filter, an array of id or object to filter according to a field. It also supports wildcards. If filter is empty, { \"classes\": \"*\" } will be the applied default behavior. With $where, dot-path fields like 'sites.name' are supported; for classes this resolves through class.site/class.sites IDs to timetable sites.","type":"object","properties":{"events":{"type":"string","enum":["*"]},"awaitingclassroom":{"description":"Admin-only. Returns lessons positioned but missing a classroom (excluding explicit no-room locks and remote/self_study modalities).","type":"string","enum":["*"]},"awaitingteacher":{"description":"Admin-only. Returns lessons positioned but missing a teacher (excluding explicit no-teacher locks; absences/substitutions handled via dedicated absences endpoints, not surfaced here).","type":"string","enum":["*"]},"classes":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"teachers":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"groups":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"classrooms":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"groupswithclasses":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"resources":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"subjects":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"types":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"teachersbyclasses":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"teachersbysubjects":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]},"students":{"oneOf":[{"type":"string","enum":["*"]},{"type":"array","items":{"oneOf":[{"type":"string","description":"ID of the given type"},{"oneOf":[{"type":"object","description":"Simple field-based filter object, such as {\"email\":\"kevin@gmail.com\"} or {\"first_name\":\"Albert\"}. Fields are matched directly (case-insensitive for strings).","additionalProperties":{"type":["string","number","boolean","null"]}},{"type":"object","description":"Structured filter object using \"$where\", e.g. {\"$where\":{\"capacity\":{\"$gte\":20}}}.","properties":{"$where":{"$ref":"#/components/schemas/WhereClause"}},"required":["$where"],"additionalProperties":false}]}]}}]}},"x-mcp":{"expose":"required"}},"description":"Filter of what is to be queried among classes, teachers, groups, classrooms, groups, groupswithclasses, resources, subjects, types, teachersbyclasses, teachersbysubjects, students, events, awaitingclassroom, awaitingteacher. Filters can be cumulative. For each filter, an array of id or object to filter according to a field. It also supports wildcards. If filter is empty, { \"classes\": \"*\" } will be the applied default behavior. With $where, dot-path fields like 'sites.name' are supported; for classes this resolves through class.site/class.sites IDs to timetable sites.","examples":{"classes":{"value":"{\"classes\":[\"6a\",\"6b\",\"6c\"]}","summary":"classes of ID 6a, 6b and 6c"},"teachers":{"value":"{\"teachers\":[\"robert-bresson\",{\"first_name\":\"Albert\"}],\"classrooms\":[\"*\"]}","summary":"teacher of ID robert-bresson, and all teachers with first name 'Albert' and all classrooms"},"classroomsAndSubjects":{"value":"{\"classrooms\":[\"site1:*\"],\"subjects\":\"*\"}","summary":"all classrooms from site ID site1, and all subjects"},"studentByEmail":{"value":"{\"students\":[{\"email\":\"kevin@gmail.com\"}]}","summary":"the student(s) with email kevin@gmail.com"},"classroomsFiltered":{"value":"{\"classrooms\":[{\"$where\":{\"capacity\":{\"$gte\":20}}}]}","summary":"all classrooms with capacity >= 20"},"classesBySiteNameWhere":{"value":"{\"classes\":[{\"$where\":{\"capacity\":{\"$gt\":30},\"sites.name\":{\"$regex\":\"avignon\"}}}]}","summary":"all classes filtered with $where: capacity > 30 and linked site name matches 'avignon'"},"virtualTeachers":{"value":"{\"teachers\":[{\"$where\":{\"virtual_name\":{\"$exists\":true}}}]}","summary":"all virtual teachers (not yet hired)"},"awaitingClassroom":{"value":"{\"awaitingclassroom\":\"*\"}","summary":"all lessons missing a classroom"},"awaitingTeacher":{"value":"{\"awaitingteacher\":\"*\"}","summary":"all lessons missing a teacher"}}},{"name":"with_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"availability":{"description":"Timeslots grouped by entity type, then by entity ID","type":"object","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","example":"2025-09-02"},"start":{"type":"string","example":"09:00"},"end":{"type":"string","example":"11:00"},"time":{"type":"integer","example":120}}}}}}},"entities":{"description":"Entity details grouped by entity type, then by entity ID","type":"object","x-conditionalOnParameter":"with_entities","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"middle_name":{"type":"string"},"virtual_name":{"type":"string"}}}}}}}}}}}}}},"/api/schedules/availability/{datesrange}/{entity}":{"get":{"tags":["Schedules"],"summary":"Retrieve available timeslots for one entity type in a date range. This route is entity-scoped and builds an ad-hoc wildcard filter internally.","description":"`os_schedules_availability-entities_get` · minimal role **student**\n\nRetrieve available timeslots for one entity type in a date range. This route is entity-scoped and builds an ad-hoc wildcard filter internally.","operationId":"os_schedules_availability-entities_get","x-module":"schedules","x-access":"student","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"entity","in":"path","required":true,"schema":{"type":"string","enum":["classes","teachers","classrooms","subjects","resources","types","groups","students","groupswithclasses","teachersbyclasses","teachersbysubjects"],"description":"Entity type for which occupancy/availability timeslots are requested"},"description":"Entity type for which occupancy/availability timeslots are requested"},{"name":"with_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"availability":{"description":"Timeslots grouped by entity type, then by entity ID","type":"object","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","example":"2025-09-02"},"start":{"type":"string","example":"09:00"},"end":{"type":"string","example":"11:00"},"time":{"type":"integer","example":120}}}}}}},"entities":{"description":"Entity details grouped by entity type, then by entity ID","type":"object","x-conditionalOnParameter":"with_entities","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"middle_name":{"type":"string"},"virtual_name":{"type":"string"}}}}}}}}}}}}}},"/api/schedules/availability/{datesrange}/{entity}/{entityId}":{"get":{"tags":["Schedules"],"summary":"Retrieve available timeslots for one explicit entity ID. Uses the same unavailability model as the collection endpoint (occupancy + absences + mandatory wishes/site wishes).","description":"`os_schedules_availability-entity_get` · minimal role **student**\n\nRetrieve available timeslots for one explicit entity ID. Uses the same unavailability model as the collection endpoint (occupancy + absences + mandatory wishes/site wishes).","operationId":"os_schedules_availability-entity_get","x-module":"schedules","x-access":"student","parameters":[{"name":"entityId","in":"path","required":true,"schema":{"type":"string","description":"Explicit entity identifier to resolve (e.g. site1:room1)"},"description":"Explicit entity identifier to resolve (e.g. site1:room1)"},{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"entity","in":"path","required":true,"schema":{"type":"string","enum":["classes","teachers","classrooms","subjects","resources","types","groups","students","groupswithclasses","teachersbyclasses","teachersbysubjects"],"description":"Entity type for which occupancy/availability timeslots are requested"},"description":"Entity type for which occupancy/availability timeslots are requested"},{"name":"with_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Include lightweight entity details (name/code and person name fields) keyed by entity type and ID."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"availability":{"description":"Timeslots grouped by entity type, then by entity ID","type":"object","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"day":{"type":"string","example":"2025-09-02"},"start":{"type":"string","example":"09:00"},"end":{"type":"string","example":"11:00"},"time":{"type":"integer","example":120}}}}}}},"entities":{"description":"Entity details grouped by entity type, then by entity ID","type":"object","x-conditionalOnParameter":"with_entities","patternProperties":{"^(classes|teachers|groups|classrooms|groupswithclasses|resources|subjects|types|teachersbyclasses|teachersbysubjects|students)$":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"first_name":{"type":"string"},"last_name":{"type":"string"},"middle_name":{"type":"string"},"virtual_name":{"type":"string"}}}}}}}}}}}}}},"/api/schedules/crossed/teachers/{datesrange}":{"get":{"tags":["Schedules"],"summary":"Retrieve lessons in linked accounts and relevant internal timetables for common teachers","description":"`os_schedules_crossed-teachers_get` · minimal role **admin**\n\nRetrieve lessons in linked accounts and relevant internal timetables for common teachers","operationId":"os_schedules_crossed-teachers_get","x-module":"schedules","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"timetable","in":"query","required":false,"schema":{"type":"string","description":"Reference timetable ID. Same-account autocross is only evaluated when this parameter is provided."},"description":"Reference timetable ID. Same-account autocross is only evaluated when this parameter is provided."},{"name":"cross_timetables","in":"query","required":false,"schema":{"type":"string","description":"Restrict same-account cross checks to these timetable IDs (string, CSV, or array). Requires timetable."},"description":"Restrict same-account cross checks to these timetable IDs (string, CSV, or array). Requires timetable."},{"name":"cross_schools","in":"query","required":false,"schema":{"type":"string","description":"Restrict linked-account cross checks to these school IDs (string, CSV, or array)"},"description":"Restrict linked-account cross checks to these school IDs (string, CSV, or array)"},{"name":"with_timetables","in":"query","required":false,"schema":{"type":"boolean","description":"Add slim timetable skeletons used for human-readable labels","x-mcp":{"default":true}},"description":"Add slim timetable skeletons used for human-readable labels"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/schedules/crossed/classrooms/{datesrange}":{"get":{"tags":["Schedules"],"summary":"Retrieve lessons in linked accounts and relevant internal timetables for common classrooms","description":"`os_schedules_crossed-classrooms_get` · minimal role **admin**\n\nRetrieve lessons in linked accounts and relevant internal timetables for common classrooms","operationId":"os_schedules_crossed-classrooms_get","x-module":"schedules","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"timetable","in":"query","required":false,"schema":{"type":"string","description":"Reference timetable ID. Same-account autocross is only evaluated when this parameter is provided."},"description":"Reference timetable ID. Same-account autocross is only evaluated when this parameter is provided."},{"name":"cross_timetables","in":"query","required":false,"schema":{"type":"string","description":"Restrict same-account cross checks to these timetable IDs (string, CSV, or array). Requires timetable."},"description":"Restrict same-account cross checks to these timetable IDs (string, CSV, or array). Requires timetable."},{"name":"cross_schools","in":"query","required":false,"schema":{"type":"string","description":"Restrict linked-account cross checks to these school IDs (string, CSV, or array)"},"description":"Restrict linked-account cross checks to these school IDs (string, CSV, or array)"},{"name":"with_timetables","in":"query","required":false,"schema":{"type":"boolean","description":"Add slim timetable skeletons used for human-readable labels","x-mcp":{"default":true}},"description":"Add slim timetable skeletons used for human-readable labels"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/schedules/crossed/lessons/{datesrange}":{"get":{"tags":["Schedules"],"summary":"Retrieve lessons in linked accounts and relevant internal timetables for common teachers & classrooms","description":"`os_schedules_crossed-lessons_get` · minimal role **admin**\n\nRetrieve lessons in linked accounts and relevant internal timetables for common teachers & classrooms","operationId":"os_schedules_crossed-lessons_get","x-module":"schedules","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"teachers","in":"query","required":false,"schema":{"type":"array","description":"Consider only those teachers","items":{"description":"Teacher ID","type":"string"}},"description":"Consider only those teachers"},{"name":"classrooms","in":"query","required":false,"schema":{"type":"array","description":"Consider only those classrooms","items":{"description":"Classroom ID","type":"string"}},"description":"Consider only those classrooms"},{"name":"classes","in":"query","required":false,"schema":{"type":"array","description":"Restrict same-account autocross extraction to those classes","items":{"description":"Class ID","type":"string"}},"description":"Restrict same-account autocross extraction to those classes"},{"name":"timetable","in":"query","required":false,"schema":{"type":"string","description":"Reference timetable ID. Same-account autocross is only evaluated when this parameter is provided."},"description":"Reference timetable ID. Same-account autocross is only evaluated when this parameter is provided."},{"name":"cross_timetables","in":"query","required":false,"schema":{"type":"string","description":"Restrict same-account cross checks to these timetable IDs (string, CSV, or array). Requires timetable."},"description":"Restrict same-account cross checks to these timetable IDs (string, CSV, or array). Requires timetable."},{"name":"cross_schools","in":"query","required":false,"schema":{"type":"string","description":"Restrict linked-account cross checks to these school IDs (string, CSV, or array)"},"description":"Restrict linked-account cross checks to these school IDs (string, CSV, or array)"},{"name":"with_timetables","in":"query","required":false,"schema":{"type":"boolean","description":"Add slim timetable skeletons used for human-readable labels","x-mcp":{"default":true}},"description":"Add slim timetable skeletons used for human-readable labels"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/schedules/panels":{"get":{"tags":["Schedules"],"summary":"Retrieve the list of schedule panels. A panel is a screen with a list of lessons with synthetic data for the day, to display in the lobby or at the classroom door","description":"`os_schedules_panels_get` · minimal role **admin**\n\nRetrieve the list of schedule panels. A panel is a screen with a list of lessons with synthetic data for the day, to display in the lobby or at the classroom door","operationId":"os_schedules_panels_get","x-module":"schedules","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"panels":{"description":"Panels, by ID","type":"object","additionalProperties":{"$ref":"#/components/schemas/Panel"}}}}}}}}},"post":{"tags":["Schedules"],"summary":"Create a new empty panel in the schedule (or copy an existing panel)","description":"`os_schedules_panels_post` · minimal role **admin**\n\nCreate a new empty panel in the schedule (or copy an existing panel)","operationId":"os_schedules_panels_post","x-module":"schedules","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Optional ID of the panel to copy"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/schedules/panels/{panelid}":{"put":{"tags":["Schedules"],"summary":"Update an existing panel in the schedule","description":"`os_schedules_panels_put` · minimal role **admin**\n\nUpdate an existing panel in the schedule","operationId":"os_schedules_panels_put","x-module":"schedules","x-access":"admin","parameters":[{"name":"panelid","in":"path","required":true,"schema":{"type":"string","description":"Panel ID"},"description":"Panel ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Panel"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Schedules"],"summary":"Delete a panel from the schedule","description":"`os_schedules_panels_delete` · minimal role **admin**\n\nDelete a panel from the schedule","operationId":"os_schedules_panels_delete","x-module":"schedules","x-access":"admin","parameters":[{"name":"panelid","in":"path","required":true,"schema":{"type":"string","description":"Panel ID to delete"},"description":"Panel ID to delete"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/dashboard/teachers/{datesrange}":{"get":{"tags":["Dashboard"],"summary":"Retrieve dashboard information/statistics for teachers over a date range: subjects, number of lessons and number of hours taught, extra and canceled hours, globally and for for each day","description":"`os_dashboard_teachers_get` · minimal role **admin**\n\nRetrieve dashboard information/statistics for teachers over a date range: subjects, number of lessons and number of hours taught, extra and canceled hours, globally and for for each day","operationId":"os_dashboard_teachers_get","x-module":"dashboard","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"digest","in":"query","required":false,"schema":{"type":"boolean","description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"teachers":{"description":"Teachers by ID","type":"object","additionalProperties":{"description":"Teacher with statistics","type":"object","properties":{"first_name":{"description":"Fist name","type":"string"},"middle_name":{"description":"Middle name (if support activated)","type":"string"},"last_name":{"description":"Last name","type":"string"},"color":{"description":"Color for chart","type":"string"},"hours":{"description":"Number of hours taught","type":"number"},"hours_actual":{"description":"Number of hours taught (actual)","type":"number"},"hours_done":{"description":"Number of hours taught with status done","type":"number"},"nb_classes":{"description":"Number of classes taught","type":"number"},"nb_courses":{"description":"Number of lessons taught","type":"number"},"subjects":{"description":"Array of the taught subjects (plain text)","type":"array","items":{"type":"string"}},"types":{"description":"Hours by course type for this teacher","type":"object","additionalProperties":{"description":"Type statistics","type":"object","properties":{"hours":{"description":"Number of hours taught (accounted)","type":"number"},"hours_actual":{"description":"Number of hours taught (actual)","type":"number"},"hours_done":{"description":"Number of hours taught with status done","type":"number"}}}},"addedcourses":{"type":"object","properties":{"class":{"description":"Class name","type":"string"},"day":{"description":"Date","type":"string","format":"date"},"minutes":{"description":"Duration in minutes","type":"number"},"subject":{"description":"Subject name","type":"string"},"start":{"description":"Start hour (format hh:mm)","type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$","examples":["08:30","14:05"]}}},"removedcourses":{"type":"object","properties":{"absence":{"description":"Absence reason","type":"string"},"class":{"description":"Class name","type":"string"},"day":{"description":"Date","type":"string","format":"date"},"minutes":{"description":"Duration in minutes","type":"number"},"subject":{"description":"Subject name","type":"string"},"start":{"description":"Start hour (format hh:mm)","type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$","examples":["08:30","14:05"]}}}}}},"datestats":{"description":"Per-date statistics, where each key is a date in the format YYYY-MM-DD","additionalProperties":{"description":"Statistics for the given date (global to all teachers)","type":"object","properties":{"courses":{"description":"Statistic for a given date, regarding the number of courses","type":"object","properties":{"total":{"description":"Total number of courses taught during the day","type":"number"},"removed":{"description":"Total number of courses canceled during the day","type":"number"}}},"hours":{"description":"Statistic for a given date, regarding the number of hours","type":"object","properties":{"total":{"description":"Total number of hours taught during the day","type":"number"},"removed":{"description":"Total number of hours canceled during the day","type":"number"}}}}}},"school_year_id":{"description":"School year id","type":"string"},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}}}}}}}},"/api/dashboard/classrooms/{datesrange}":{"get":{"tags":["Dashboard"],"summary":"Retrieve dashboard information/statistics for classrooms over a date range: number of courses/days/hours, advanced statistics with hours and occupation, warnings with overloading and underusage, globally and for each day","description":"`os_dashboard_classrooms_get` · minimal role **admin**\n\nRetrieve dashboard information/statistics for classrooms over a date range: number of courses/days/hours, advanced statistics with hours and occupation, warnings with overloading and underusage, globally and for each day","operationId":"os_dashboard_classrooms_get","x-module":"dashboard","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"digest","in":"query","required":false,"schema":{"type":"boolean","description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"totalhours":{"description":"Total number of hours (in minutes)","type":"number"},"classrooms":{"description":"Classrooms by ID with statistics details","type":"object","properties":{"capacity":{"description":"Capacity of the classroom (number of seats)","type":"integer"},"specialisation":{"description":"Specialisation of the classroom (free label). To be associated with specific subjects (e.g. stadium with PE)","type":"string"},"building":{"description":"Building of the classroom (can also be used to specify the floor)","type":"string"},"description":{"description":"Description of the room","type":"string"},"tags":{"description":"Different tags","type":"array","items":{"type":"string"}},"nb_courses":{"description":"Total number of courses","type":"number"},"nb_days":{"description":"Number of days the classroom is open","type":"number"},"nb_hours":{"description":"Total number of hours","type":"number"},"hours_per_day_mean":{"description":"Mean of hours per day","type":"number"},"hours_per_day_median":{"description":"Median of hours per day","type":"number"},"hours_per_day_iqr":{"description":"Interquartile range of hours per day","type":"number"},"hours_per_day_standdev":{"description":"Standard deviation of hours per day","type":"number"},"hours_per_day_lowest":{"description":"Lowest hour usage for the days","type":"number"},"hours_per_day_highest":{"description":"Highest hour usage for the days","type":"number"},"ratio":{"description":"Ratio of the number of hours of this classroom / total hours of all classrooms","type":"number"},"nb_students_mean":{"description":"Mean of number of students","type":"number"},"nb_students_median":{"description":"Median of number of students","type":"number"},"nb_students_iqr":{"description":"Interquartile range of number of students","type":"number"},"nb_students_standdev":{"description":"Standard deviation of number of students","type":"number"},"nb_students_lowest":{"description":"Lowest of number of students","type":"number"},"nb_students_highest":{"description":"Highest of number of students","type":"number"},"courses_toohigh":{"description":"List of lessons when capacity is overloaded (> 100%)","type":"array","items":{"type":"object","properties":{"class":{"description":"Class name","type":"string"},"day":{"description":"Date","type":"string","format":"date"},"group":{"description":"Group name","type":"string"},"minutes":{"description":"Duration in minutes","type":"number"},"nb_students":{"description":"Number of students","type":"number"},"start":{"description":"Start hour (format hh:mm)","type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$","examples":["08:30","14:05"]},"subjectobject":{"description":"Subject object","type":"string","properties":{"name":{"description":"Subject name","type":"string"},"code":{"description":"Subject code","type":"string"}}}}}},"courses_toolow":{"description":"List of lessons when capacity is uderused (< 25%)","type":"array","items":{"type":"object","properties":{"class":{"description":"Class name","type":"string"},"day":{"description":"Date","type":"string","format":"date"},"group":{"description":"Group name","type":"string"},"minutes":{"description":"Duration in minutes","type":"number"},"nb_students":{"description":"Number of students","type":"number"},"start":{"description":"Start hour (format hh:mm)","type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$","examples":["08:30","14:05"]},"subjectobject":{"description":"Subject object","type":"string","properties":{"name":{"description":"Subject name","type":"string"},"code":{"description":"Subject code","type":"string"}}}}}},"name":{"description":"Classroom name","type":"string"},"site":{"description":"Site name","type":"string"},"color":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}},"datestats":{"description":"Per-date statistics, where each key is a date in the format YYYY-MM-DD","additionalProperties":{"description":"Per-classroom statistics for the given date, where each key is the classroom ID with format <siteid>:<classroomid>","type":"object","additionalProperties":{"description":"Statistics for the specific classroom","type":"object","properties":{"nb_courses":{"description":"Number of lessons","type":"number"},"nb_hours":{"description":"Number of hours","type":"number"}}}}},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}},"school_year_id":{"description":"School year id","type":"string"}}}}}}}}},"/api/dashboard/resources/{datesrange}":{"get":{"tags":["Dashboard"],"summary":"Retrieve dashboard information/statistics for resources over a date range: number of courses/days/hours, advanced statistics with hours and occupation, globally and for each day","description":"`os_dashboard_resources_get` · minimal role **admin**\n\nRetrieve dashboard information/statistics for resources over a date range: number of courses/days/hours, advanced statistics with hours and occupation, globally and for each day","operationId":"os_dashboard_resources_get","x-module":"dashboard","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"digest","in":"query","required":false,"schema":{"type":"boolean","description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"totalhours":{"description":"Total number of hours (in minutes)","type":"number"},"resources":{"type":"object","properties":{"number":{"description":"How many of this resource","type":"integer"},"nb_courses":{"description":"Total number of courses","type":"number"},"nb_days":{"description":"Number of days the resource is used","type":"number"},"nb_hours":{"description":"Total number of hours","type":"number"},"hours_per_day_mean":{"description":"Mean of hours per day","type":"number"},"hours_per_day_median":{"description":"Median of hours per day","type":"number"},"hours_per_day_iqr":{"description":"Interquartile range of hours per day","type":"number"},"hours_per_day_standdev":{"description":"Standard deviation of hours per day","type":"number"},"hours_per_day_lowest":{"description":"Lowest hour usage for the days","type":"number"},"hours_per_day_highest":{"description":"Highest hour usage for the days","type":"number"},"ratio":{"description":"Ratio of the number of hours of this resource / total hours of all resources","type":"number"},"number_per_day_mean":{"description":"Mean of how much from this resource is used per day for courses using it","type":"number"},"number_per_day_median":{"description":"Median of how much from this resource is used per day for courses using it","type":"number"},"number_per_day_iqr":{"description":"Interquartile range of how much from this resource is used per day for courses using it","type":"number"},"number_per_day_standdev":{"description":"Standard deviation of how much from this resource is used per day for courses using it","type":"number"},"number_per_day_lowest":{"description":"Lowest of number of how much from this resource is used per day for courses using it","type":"number"},"number_per_day_highest":{"description":"Highest of number of how much from this resource is used per day for courses using it","type":"number"},"name":{"description":"Resource name","type":"string"},"site":{"description":"Site name","type":"string"},"color":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}},"datestats":{"description":"Per-date statistics, where each key is a date in the format YYYY-MM-DD","additionalProperties":{"description":"Per-resource statistics for the given date, where each key is the resource ID with format <siteid>:<resourceid>","type":"object","additionalProperties":{"description":"Statistics for the specific resource","type":"object","properties":{"nb_courses":{"description":"Number of lessons","type":"number"},"nb_hours":{"description":"Number of hours","type":"number"}}}}},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}},"school_year_id":{"description":"School year id","type":"string"}}}}}}}}},"/api/dashboard/subjects/{datesrange}":{"get":{"tags":["Dashboard"],"summary":"Retrieve dashboard information/statistics for subjects over a date range: number of courses/days/hours, globally and for each day","description":"`os_dashboard_subjects_get` · minimal role **admin**\n\nRetrieve dashboard information/statistics for subjects over a date range: number of courses/days/hours, globally and for each day","operationId":"os_dashboard_subjects_get","x-module":"dashboard","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"digest","in":"query","required":false,"schema":{"type":"boolean","description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"levels":{"type":"array","items":{"type":"string"}},"totalhours":{"description":"Total number of hours (in minutes)","type":"number"},"subjects":{"description":"Subjects by ID with statistics details","type":"object","additionalProperties":{"description":"Subject with statistics","type":"object","properties":{"name":{"description":"Name of the subject","type":"string"},"code":{"description":"Code of the subject","type":"string"},"nb_courses":{"description":"Number of lessons with this subject","type":"number"},"nb_days":{"description":"Number of days with this subject","type":"number"},"nb_hours":{"description":"Number of hours with this subject","type":"number"},"modalities":{"description":"Modality breakdown for this subject, by modality ID","type":"object","additionalProperties":{"description":"Statistics for one modality","type":"object","properties":{"nb_courses":{"description":"Number of lessons with this modality","type":"number"},"nb_hours":{"description":"Number of hours with this modality","type":"number"},"ratio":{"description":"Ratio of the hours with this modality / total hours of the subject","type":"number"}}}},"hours_done":{"description":"Number of hours with status done for this subject","type":"number"},"ratio":{"description":"Ratio of the number of hours of this subject / total hours of all subjects","type":"number"},"teachers":{"description":"Teachers teaching this subject, by ID, with statistics","type":"object","additionalProperties":{"description":"Teacher statistics","type":"object","properties":{"nb_courses":{"description":"Number of lessons for this teacher with this subject","type":"number"},"nb_hours":{"description":"Number of hours for this teacher with this subject","type":"number"}}}},"color":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}},"teachers":{"description":"Teachers by ID","type":"object","additionalProperties":{"description":"Teacher","type":"object","properties":{"first_name":{"description":"Fist name","type":"string"},"middle_name":{"description":"Middle name (if support activated)","type":"string"},"last_name":{"description":"Last name","type":"string"},"color":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}},"datestats":{"description":"Per-date statistics, where each key is a date in the format YYYY-MM-DD","additionalProperties":{"description":"Per-subject statistics for the given date, where each key is the subject ID","type":"object","additionalProperties":{"description":"Statistics for the specific subject","type":"object","properties":{"nb_courses":{"description":"Number of lessons","type":"number"},"nb_hours":{"description":"Number of hours","type":"number"}}}}},"school_year_id":{"description":"School year id","type":"string"},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}}}}}}}},"/api/dashboard/classes/{datesrange}":{"get":{"tags":["Dashboard"],"summary":"Retrieve dashboard information/statistics for classes over a date range: number of courses/days/hours, globally and for each day","description":"`os_dashboard_classes_get` · minimal role **admin**\n\nRetrieve dashboard information/statistics for classes over a date range: number of courses/days/hours, globally and for each day","operationId":"os_dashboard_classes_get","x-module":"dashboard","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"digest","in":"query","required":false,"schema":{"type":"boolean","description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"levels":{"type":"array","items":{"type":"string"}},"totalhours":{"description":"Total number of hours (in minutes)","type":"number"},"subjects":{"description":"Subjects","type":"object","additionalProperties":{"description":"Subject","type":"object","properties":{"name":{"description":"Name of the subject","type":"string"},"code":{"description":"Code of the subject","type":"string"}}}},"classes":{"description":"All classes by ID with statistics details","type":"object","additionalProperties":{"description":"Class with statistics","type":"object","properties":{"nb_courses":{"description":"Number of lessons with this subject","type":"number"},"nb_days":{"description":"Number of days with this subject","type":"number"},"nb_hours":{"description":"Number of hours with this subject","type":"number"},"modalities":{"description":"Modality breakdown for this class, by modality ID","type":"object","additionalProperties":{"description":"Statistics for one modality","type":"object","properties":{"nb_courses":{"description":"Number of lessons with this modality","type":"number"},"nb_hours":{"description":"Number of hours with this modality","type":"number"},"ratio":{"description":"Ratio of the hours with this modality / total hours of the class","type":"number"}}}},"hours_done":{"description":"Number of hours with status done for this class","type":"number"},"ratio":{"description":"Ratio of the number of hours of this subject / total hours of all subjects","type":"number"},"groups":{"description":"Groups of the class (by ID)","type":"object","additionalProperties":{"description":"Group with statistics","type":"object","properties":{"code":{"description":"Code of the group","type":"string"},"name":{"description":"Name of the group","type":"string"},"nb_courses":{"description":"Number of lessons with this subject","type":"number"},"nb_hours":{"description":"Number of hours with this subject","type":"number"},"studentsnb":{"description":"Number of students","type":"number"}}}},"subjects":{"description":"Subjects for this class, by ID, with statistics","type":"object","additionalProperties":{"description":"Statistics of subject for this class","type":"object","properties":{"nb_courses":{"description":"Number of lessons for this subject with this class","type":"number"},"nb_hours":{"description":"Number of hours for this subject with this class","type":"number"}}}},"teachers":{"description":"Teachers teaching in this class, by ID, with statistics","type":"object","additionalProperties":{"description":"Teacher statistics","type":"object","properties":{"nb_courses":{"description":"Number of lessons for this teacher with this class","type":"number"},"nb_hours":{"description":"Number of hours for this teacher with this clas","type":"number"}}}},"name":{"description":"Class name","type":"string"},"color":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]},"studentsnb":{"description":"Number of students","type":"number"}}}},"teachers":{"description":"Teachers (by ID)","type":"object","additionalProperties":{"description":"Teacher","type":"object","properties":{"first_name":{"description":"Fist name","type":"string"},"middle_name":{"description":"Middle name (if support activated)","type":"string"},"last_name":{"description":"Last name","type":"string"},"color":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}},"datestats":{"description":"Per-date statistics, where each key is a date in the format YYYY-MM-DD","additionalProperties":{"description":"Per-class statistics for the given date, where each key is the class ID","type":"object","additionalProperties":{"description":"Statistics for the specific class","type":"object","properties":{"nb_courses":{"description":"Number of lessons","type":"number"},"nb_hours":{"description":"Number of hours","type":"number"}}}}},"school_year_id":{"description":"School year id","type":"string"},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}}}}}}}},"/api/dashboard/students/{datesrange}":{"get":{"tags":["Dashboard"],"summary":"Retrieve dashboard information/statistics for students over a date rangenumber of courses/days/hours, globally and for each day, also with absence statistics","description":"`os_dashboard_students_get` · minimal role **admin**\n\nRetrieve dashboard information/statistics for students over a date rangenumber of courses/days/hours, globally and for each day, also with absence statistics","operationId":"os_dashboard_students_get","x-module":"dashboard","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}},{"name":"digest","in":"query","required":false,"schema":{"type":"boolean","description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant.","x-mcp":{"expose":"server-fixed","default":true}},"description":"Compact mode: lists every entity but omits per-day breakdowns and distribution stats. Always on for the in-app assistant."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"levels":{"type":"array","items":{"type":"string"}},"totalhours":{"description":"Total number of hours (in minutes)","type":"number"},"subjects":{"description":"Subjects","type":"object","additionalProperties":{"description":"Subject","type":"object","properties":{"name":{"description":"Name of the subject","type":"string"},"code":{"description":"Code of the subject","type":"string"}}}},"classes":{"description":"All classes by ID with statistics details","type":"object","additionalProperties":{"description":"Class statistics","type":"object","properties":{"groups":{"description":"Groups of the class (by ID)","type":"object","additionalProperties":{"description":"Group with statistics","type":"object","properties":{"code":{"description":"Code of the group","type":"string"},"name":{"description":"Name of the group","type":"string"},"nb_courses":{"description":"Number of lessons with this group","type":"number"},"nb_hours":{"description":"Number of hours with this group","type":"number"},"studentsnb":{"description":"Number of students","type":"number"}}}},"name":{"description":"Class name","type":"string"}}}},"students":{"description":"All students by ID with statistics details","type":"object","additionalProperties":{"description":"Student with statistics","type":"object","properties":{"first_name":{"description":"Fist name","type":"string"},"middle_name":{"description":"Middle name (if support activated)","type":"string"},"last_name":{"description":"Last name","type":"string"},"gender":{"description":"Gender (Male, Female, Unknown)","type":"string","enum":["M","F","U"]},"nb_courses":{"description":"Number of lessons for this student","type":"number"},"nb_courses_absences":{"description":"Number of lessons when the student has been absent","type":"number"},"nb_days":{"description":"Number of days for this student","type":"number"},"nb_days_absences":{"description":"Number of days when the student has been absent","type":"number"},"nb_hours":{"description":"Number of hours for this student","type":"number"},"hours_done":{"description":"Number of hours with status done for this student","type":"number"},"nb_hours_absences":{"description":"Number of hours when the student has been absent","type":"number"},"subjects":{"description":"Subject for this class, by ID, with statistics","type":"object","properties":{"nb_courses":{"description":"Number of lessons for this student with this subject","type":"number"},"nb_courses_absences":{"description":"Number of lessons with this subject when the student has been absent","type":"number"},"nb_hours":{"description":"Number of hours for this student with this subject","type":"number"},"nb_hours_absences":{"description":"Number of hours with this subject when the student has been absent","type":"number"}}},"teachers":{"description":"Teachers teaching in this class, by ID, with statistics","type":"object","additionalProperties":{"description":"Teacher statistics","type":"object","properties":{"nb_courses":{"description":"Number of lessons for this teacher with this class","type":"number"},"nb_hours":{"description":"Number of hours for this teacher with this clas","type":"number"}}}},"color":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}},"teachers":{"description":"Teachers, by ID","type":"object","additionalProperties":{"description":"Teacher","type":"object","properties":{"first_name":{"description":"Fist name","type":"string"},"middle_name":{"description":"Middle name (if support activated)","type":"string"},"last_name":{"description":"Last name","type":"string"},"color":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}},"datestats":{"description":"Per-date statistics, where each key is a date in the format YYYY-MM-DD","additionalProperties":{"description":"Per-student statistics for the given date, where each key is the student ID","type":"object","additionalProperties":{"description":"Statistics for the specific student","type":"object","properties":{"nb_courses":{"description":"Number of lessons","type":"number"},"nb_courses_absences":{"description":"Number of lessons the student was absent","type":"number"},"nb_hours":{"description":"Number of hours","type":"number"},"nb_hours_absences":{"description":"Number of hours the student was absent","type":"number"}}}}},"school_year_id":{"description":"School year id","type":"string"},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}}}}}}}},"/api/absences/teachers":{"get":{"tags":["Absences"],"summary":"List teacher absences over the period (which teachers are absent and when). Use this to list, count, or check teacher absences.","description":"`os_absences_teachers_get` · minimal role **teacher**\n\nList teacher absences over the period (which teachers are absent and when). Use this to list, count, or check teacher absences.","operationId":"os_absences_teachers_get","x-module":"absences","x-access":"teacher","parameters":[{"name":"school_year","in":"query","required":false,"schema":{"description":"School year id","type":"string"},"description":"School year id"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absences":{"description":"Absences of teachers","type":"object","additionalProperties":{"description":"Absences for a specific teacher (by ID of teacher, then by index)","type":"object","patternProperties":{"^[0-9]+$":{"type":"object","required":["date_start","reason"],"description":"Absence of the teacher","properties":{"date_start":{"description":"Start date (YYYY-MM-DD)","type":"string","format":"date"},"date_end":{"description":"End date (YYYY-MM-DD)","type":"string","format":"date"},"reason":{"description":"Reason of the absence (ID refering to a translation key, OR custom label)","type":"string"},"tstp":{"description":"Creation timestamp (since EPOCH)","type":"integer"},"createdby":{"description":"User creating this absence","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"comment":{"description":"Free comment","type":"string"},"hours":{"description":"Specific optional hour spans (all day/date, or with specific hours)","type":"array","items":{"type":"object","required":["day"],"properties":{"begin":{"description":"Start in minutes","type":"integer"},"end":{"description":"End in minutes","type":"integer"},"day":{"description":"Date of the day (YYYY-MM-DD)","type":"string","format":"date"}}}},"statusby":{"description":"User last modifying the status","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"statuststp":{"description":"Status update timestamp (since EPOCH)","type":"number"},"subjects":{"description":"Absence only for these subjects. A teacher can only be unavailable for chemistry but ok for physics","type":"array","items":{"type":"string"}},"classes":{"description":"Absence only for those classes. A teacher can only be allergic to one specific class","type":"array","items":{"type":"string"}},"substitutes":{"description":"All substitution rules","type":"array","items":{"description":"Substitution rule for a teacher's absence","type":"object","oneOf":[{"type":"object","properties":{"substitute":{"description":"Substitute teacher's name","type":"string"},"date_start":{"description":"Start date of the substitution rule (YYYY-MM-DD)","type":"string","format":"date"},"date_end":{"description":"End date of the substitution rule (YYYY-MM-DD)","type":"string","format":"date"},"hours":{"description":"Time slots of the substitution rule","type":"array","items":{"type":"object","required":["day"],"properties":{"begin":{"description":"Start time of the slot (in minutes)","type":"number"},"end":{"description":"End time of the slot (in minutes)","type":"number"},"day":{"description":"Date concerned (YYYY-MM-DD)","type":"string","format":"date"}}}},"classes":{"description":"List of classes concerned by the rule","type":"array","items":{"type":"string"}},"subjects":{"description":"List of subjects concerned by the rule","type":"array","items":{"type":"string"}},"comment":{"description":"Comment or additional information about the rule","type":"string"}},"required":["substitute","date_start"]},{"type":"object","properties":{"substitute":{"description":"Substitute teacher's name","type":"string"},"course":{"description":"Specific substituted lessons. As we don't use ID on lessons, we need to store a complete footprint","type":"object","required":["class","subject","day","period"],"properties":{"class":{"description":"Class of the substituted lesson","type":"string"},"subject":{"description":"Subject of the substituted lesson","type":"string"},"group":{"description":"Group of the substituted lesson (optional)","type":"string"},"day":{"description":"Day of the week of the substituted lesson","type":"string"},"period":{"description":"Period of the substituted lesson","type":"integer"}}}},"required":["substitute","course"]}]}},"status":{"description":"Status of the absence:\n- `ok`: validated\n- `rejected`: refused by administration (no authorization)\n- `aborted`: canceled by teacher/admin\n- `ko`: canceled for technical reason","type":"string","enum":["ok","rejected","pending","aborted","ko"],"default":"ok","examples":["ok","rejected","aborted","ko"]}}}}}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"school_years":{"description":"School years (academic years)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}},"classes":{"description":"All classes by ID","type":"object","additionalProperties":{"description":"Class","type":"object","properties":{"name":{"description":"Class name","type":"string"}}}},"teachers":{"description":"List of teachers","type":"object","additionalProperties":{"$ref":"#/components/schemas/TeacherMinimal"}},"school_year_id":{"description":"School year id","type":"string"},"subjects":{"description":"Subjects","type":"object","additionalProperties":{"description":"Subject","type":"object","properties":{"name":{"description":"Name of the subject","type":"string"},"code":{"description":"Code of the subject","type":"string"},"short":{"description":"Short name of the subject, used to be displayed by default on the grid/schedule","type":"string"},"type":{"description":"Type of the subject (e.g. exam, practical work...)","type":"string"}}}}}}}}}}}},"/api/absences/teachers/{entity}":{"post":{"tags":["Absences"],"summary":"Create a new absence for a specific teacher","description":"`os_absences_teachers_post` · minimal role **teacher**\n\nCreate a new absence for a specific teacher","operationId":"os_absences_teachers_post","x-module":"absences","x-access":"teacher","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbsenceTeacher"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absence":{"$ref":"#/components/schemas/AbsenceTeacher"},"id":{"description":"ID of the created absence","type":"string"},"tstp":{"description":"Creation timestamp (since EPOCH)","type":"integer"}}}}}}}}},"/api/absences/teachers/{entity}/{absenceid}":{"put":{"tags":["Absences"],"summary":"Update an existing absence for a specific teacher","description":"`os_absences_teachers_put` · minimal role **teacher**\n\nUpdate an existing absence for a specific teacher","operationId":"os_absences_teachers_put","x-module":"absences","x-access":"teacher","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbsenceTeacher"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absence":{"$ref":"#/components/schemas/AbsenceTeacher"}}}}}}}},"delete":{"tags":["Absences"],"summary":"Delete a teacher absence","description":"`os_absences_teachers_delete` · minimal role **teacher**\n\nDelete a teacher absence","operationId":"os_absences_teachers_delete","x-module":"absences","x-access":"teacher","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/absences/teachers/{entity}/{absenceid}/status":{"put":{"tags":["Absences"],"summary":"Update the status of a teacher absence","description":"`os_absences_teachers-status_put` · minimal role **teacher**\n\nUpdate the status of a teacher absence","operationId":"os_absences_teachers-status_put","x-module":"absences","x-access":"teacher","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/AbsenceTeacherStatus"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/absences/teachers/{teacher}/{absenceid}/substitutes":{"get":{"tags":["Absences"],"summary":"Retrieve the list of substitutes for a teacher absence","description":"`os_absences_teachers-substitutes_get` · minimal role **teacher**\n\nRetrieve the list of substitutes for a teacher absence","operationId":"os_absences_teachers-substitutes_get","x-module":"absences","x-access":"teacher","parameters":[{"name":"teacher","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"lessons":{"description":"List of lessons for the absence","type":"array","items":{"$ref":"#/components/schemas/LessonSchedule"}},"timetables":{"description":"List of timetables for the absence","type":"array","items":{"$ref":"#/components/schemas/Timetable"}},"substitutes":{"description":"List of substitutes for the absence","type":"array","items":{"$ref":"#/components/schemas/AbsenceTeacherSubstitute"}}}}}}}}},"put":{"tags":["Absences"],"summary":"Define all substitutes for a teacher absence","description":"`os_absences_teachers-substitutes_put` · minimal role **teacher**\n\nDefine all substitutes for a teacher absence","operationId":"os_absences_teachers-substitutes_put","x-module":"absences","x-access":"teacher","parameters":[{"name":"teacher","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"substitutes":{"type":"array","description":"List of substitutes to assign to the absence","items":{"$ref":"#/components/schemas/AbsenceTeacherSubstitute"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/absences/classes":{"get":{"tags":["Absences"],"summary":"List class absences over the period (which classes are absent and when). Use this to list, count, or check class absences.","description":"`os_absences_classes_get` · minimal role **student**\n\nList class absences over the period (which classes are absent and when). Use this to list, count, or check class absences.","operationId":"os_absences_classes_get","x-module":"absences","x-access":"student","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absences":{"description":"Absences of classes (= canceled lessons on a time span)","type":"object","additionalProperties":{"description":"Absences of specific class (by ID of class, then by index)","type":"object","patternProperties":{"^[0-9]+$":{"type":"object","required":["date_start","reason"],"description":"Absence of the class","properties":{"date_start":{"description":"Start date (YYYY-MM-DD)","type":"string","format":"date"},"date_end":{"description":"End date (YYYY-MM-DD)","type":"string","format":"date"},"reason":{"description":"Reason of the absence (ID refering to a translation key, OR custom label)","type":"string"},"tstp":{"description":"Creation timestamp (since EPOCH)","type":"integer"},"createdby":{"description":"User creating this absence","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"comment":{"description":"Free comment","type":"string"},"hours":{"description":"Specific optional hour spans (all day/date, or with specific hours)","type":"array","items":{"type":"object","required":["day"],"properties":{"begin":{"description":"Start in minutes","type":"integer"},"end":{"description":"End in minutes","type":"integer"},"day":{"description":"Date of the day (YYYY-MM-DD)","type":"string","format":"date"}}}},"statusby":{"description":"User last modifying the status","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"statuststp":{"description":"Status update timestamp (since EPOCH)","type":"number"},"status":{"description":"Status of the absence","type":"string","enum":["ok","aborted"]}}}}}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"school_years":{"description":"School years (academic years)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}},"classes":{"description":"All classes by ID","type":"object","additionalProperties":{"description":"Class","type":"object","properties":{"name":{"description":"Class name","type":"string"}}}},"teachers":{"description":"List of teachers","type":"object","additionalProperties":{"$ref":"#/components/schemas/TeacherMinimal"}},"school_year_id":{"description":"School year id","type":"string"},"subjects":{"description":"Subjects","type":"object","additionalProperties":{"description":"Subject","type":"object","properties":{"name":{"description":"Name of the subject","type":"string"},"code":{"description":"Code of the subject","type":"string"},"short":{"description":"Short name of the subject, used to be displayed by default on the grid/schedule","type":"string"},"type":{"description":"Type of the subject (e.g. exam, practical work...)","type":"string"}}}}}}}}}}}},"/api/absences/classes/{entity}":{"post":{"tags":["Absences"],"summary":"Create a new absence for a specific class","description":"`os_absences_classes_post` · minimal role **admin**\n\nCreate a new absence for a specific class","operationId":"os_absences_classes_post","x-module":"absences","x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbsenceClass"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absence":{"$ref":"#/components/schemas/AbsenceClass"},"id":{"description":"ID of the created absence","type":"string"},"tstp":{"description":"Creation timestamp (since EPOCH)","type":"integer"}}}}}}}}},"/api/absences/classes/{entity}/{absenceid}":{"put":{"tags":["Absences"],"summary":"Update an existing absence for a specific class","description":"`os_absences_classes_put` · minimal role **admin**\n\nUpdate an existing absence for a specific class","operationId":"os_absences_classes_put","x-module":"absences","x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbsenceClass"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absence":{"$ref":"#/components/schemas/AbsenceClass"}}}}}}}},"delete":{"tags":["Absences"],"summary":"Delete a class absence","description":"`os_absences_classes_delete` · minimal role **admin**\n\nDelete a class absence","operationId":"os_absences_classes_delete","x-module":"absences","x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/absences/classes/{entity}/{absenceid}/status":{"put":{"tags":["Absences"],"summary":"Update the status of a class absence","description":"`os_absences_classes-status_put` · minimal role **admin**\n\nUpdate the status of a class absence","operationId":"os_absences_classes-status_put","x-module":"absences","x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/AbsenceTeacherStatus"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/absences/staff":{"get":{"tags":["Absences"],"summary":"Retrieve the list of staff absences","description":"`os_absences_staff_get` · minimal role **staff**\n\nRetrieve the list of staff absences","operationId":"os_absences_staff_get","x-module":"absences","x-access":"staff","parameters":[{"name":"school_year","in":"query","required":false,"schema":{"description":"School year id","type":"string"},"description":"School year id"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absences":{"description":"Absences of staff","type":"object","additionalProperties":{"description":"Absences for a specific staff member (by ID)","type":"object","patternProperties":{"^[0-9]+$":{"type":"object","required":["date_start","reason"],"description":"Absence of the staff member","properties":{"date_start":{"description":"Start date (YYYY-MM-DD)","type":"string","format":"date"},"date_end":{"description":"End date (YYYY-MM-DD)","type":"string","format":"date"},"reason":{"description":"Reason of the absence (ID refering to a translation key, OR custom label)","type":"string"},"tstp":{"description":"Creation timestamp (since EPOCH)","type":"integer"},"createdby":{"description":"User creating this absence","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"comment":{"description":"Free comment","type":"string"},"hours":{"description":"Specific optional hour spans (all day/date, or with specific hours)","type":"array","items":{"type":"object","required":["day"],"properties":{"begin":{"description":"Start in minutes","type":"integer"},"end":{"description":"End in minutes","type":"integer"},"day":{"description":"Date of the day (YYYY-MM-DD)","type":"string","format":"date"}}}},"statusby":{"description":"User last modifying the status","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"statuststp":{"description":"Status update timestamp (since EPOCH)","type":"number"},"subjects":{"description":"Specific subjects (ID) to exclude. For example, the staff member can only be absent to PE course","type":"array","items":{"type":"string"}},"status":{"description":"Status of the absence:\n- `ok`: validated\n- `rejected`: refused by administration (no authorization)\n- `aborted`: canceled by staff member/admin\n- `ko`: canceled for technical reason","type":"string","enum":["ok","rejected","pending","aborted","ko"],"default":"ok","examples":["ok","rejected","aborted","ko"]}}}}}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"school_years":{"description":"School years (academic years)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"},"staff":{"description":"List of staff members","type":"object","additionalProperties":{"$ref":"#/components/schemas/UserMinimal"}}},"school_year_id":{"description":"School year id","type":"string"}}}}}}}}},"/api/absences/staff/{entity}":{"post":{"tags":["Absences"],"summary":"Create a new absence for a specific staff member","description":"`os_absences_staff_post` · minimal role **staff**\n\nCreate a new absence for a specific staff member","operationId":"os_absences_staff_post","x-module":"absences","x-access":"staff","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"staff ID"},"description":"staff ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbsenceStaff"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absence":{"$ref":"#/components/schemas/AbsenceStaff"},"id":{"description":"ID of the created absence","type":"string"},"tstp":{"description":"Creation timestamp (since EPOCH)","type":"integer"}}}}}}}}},"/api/absences/staff/{entity}/{absenceid}":{"put":{"tags":["Absences"],"summary":"Update an existing absence for a specific staff member","description":"`os_absences_staff_put` · minimal role **staff**\n\nUpdate an existing absence for a specific staff member","operationId":"os_absences_staff_put","x-module":"absences","x-access":"staff","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"staff ID"},"description":"staff ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbsenceStaff"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absence":{"$ref":"#/components/schemas/AbsenceStaff"}}}}}}}},"delete":{"tags":["Absences"],"summary":"Delete a staff member absence","description":"`os_absences_staff_delete` · minimal role **staff**\n\nDelete a staff member absence","operationId":"os_absences_staff_delete","x-module":"absences","x-access":"staff","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"staff ID"},"description":"staff ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/absences/staff/{entity}/{absenceid}/status":{"put":{"tags":["Absences"],"summary":"Update the status of a staff member absence","description":"`os_absences_staff-status_put` · minimal role **staff**\n\nUpdate the status of a staff member absence","operationId":"os_absences_staff-status_put","x-module":"absences","x-access":"staff","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"staff ID"},"description":"staff ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/AbsenceStaffStatus"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/absences/students":{"get":{"tags":["Absences"],"summary":"List student absences over the period (which students are absent and when). Use this to list, count, or check student absences.","description":"`os_absences_students_get` · minimal role **student**\n\nList student absences over the period (which students are absent and when). Use this to list, count, or check student absences.","operationId":"os_absences_students_get","x-module":"absences","x-access":"student","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absences":{"description":"Absences of students","type":"object","additionalProperties":{"description":"Absences for a specific student (by ID)","type":"object","patternProperties":{"^[0-9]+$":{"type":"object","required":["date_start","reason"],"description":"Absence of the student","properties":{"date_start":{"description":"Start date (YYYY-MM-DD)","type":"string","format":"date"},"date_end":{"description":"End date (YYYY-MM-DD)","type":"string","format":"date"},"reason":{"description":"Reason of the absence (ID refering to a translation key, OR custom label)","type":"string"},"tstp":{"description":"Creation timestamp (since EPOCH)","type":"integer"},"createdby":{"description":"User creating this absence","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"comment":{"description":"Free comment","type":"string"},"hours":{"description":"Specific optional hour spans (all day/date, or with specific hours)","type":"array","items":{"type":"object","required":["day"],"properties":{"begin":{"description":"Start in minutes","type":"integer"},"end":{"description":"End in minutes","type":"integer"},"day":{"description":"Date of the day (YYYY-MM-DD)","type":"string","format":"date"}}}},"statusby":{"description":"User last modifying the status","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"statuststp":{"description":"Status update timestamp (since EPOCH)","type":"number"},"subjects":{"description":"Specific subjects (ID) to exclude. For example, the student can only be absent to PE course","type":"array","items":{"type":"string"}},"status":{"description":"Status of the absence:\n- `ok`: validated\n- `rejected`: refused by administration (no authorization)\n- `aborted`: canceled by student/admin\n- `ko`: canceled for technical reason","type":"string","enum":["ok","rejected","pending","aborted","ko"],"default":"ok","examples":["ok","rejected","aborted","ko"]}}}}}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"school_years":{"description":"School years (academic years)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}},"students":{"description":"List of students","type":"object","additionalProperties":{"$ref":"#/components/schemas/UserMinimal"}},"teachers":{"description":"List of teachers","type":"object","additionalProperties":{"$ref":"#/components/schemas/TeacherMinimal"}},"school_year_id":{"description":"School year id","type":"string"},"subjects":{"description":"Subjects","type":"object","additionalProperties":{"description":"Subject","type":"object","properties":{"name":{"description":"Name of the subject","type":"string"},"code":{"description":"Code of the subject","type":"string"},"short":{"description":"Short name of the subject, used to be displayed by default on the grid/schedule","type":"string"},"type":{"description":"Type of the subject (e.g. exam, practical work...)","type":"string"}}}}}}}}}}}},"/api/absences/students/{entity}":{"post":{"tags":["Absences"],"summary":"Create a new absence for a specific student","description":"`os_absences_students_post` · minimal role **student**\n\nCreate a new absence for a specific student","operationId":"os_absences_students_post","x-module":"absences","x-access":"student","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"student ID"},"description":"student ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbsenceStudent"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absence":{"$ref":"#/components/schemas/AbsenceStudent"},"id":{"description":"ID of the created absence","type":"string"},"tstp":{"description":"Creation timestamp (since EPOCH)","type":"integer"}}}}}}}}},"/api/absences/students/{entity}/{absenceid}":{"put":{"tags":["Absences"],"summary":"Update an existing absence for a specific student","description":"`os_absences_students_put` · minimal role **student**\n\nUpdate an existing absence for a specific student","operationId":"os_absences_students_put","x-module":"absences","x-access":"student","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"student ID"},"description":"student ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/AbsenceStudent"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absence":{"$ref":"#/components/schemas/AbsenceStudent"}}}}}}}},"delete":{"tags":["Absences"],"summary":"Delete a student absence","description":"`os_absences_students_delete` · minimal role **student**\n\nDelete a student absence","operationId":"os_absences_students_delete","x-module":"absences","x-access":"student","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"student ID"},"description":"student ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/absences/students/{entity}/{absenceid}/status":{"put":{"tags":["Absences"],"summary":"Update the status of a student absence","description":"`os_absences_students-status_put` · minimal role **student**\n\nUpdate the status of a student absence","operationId":"os_absences_students-status_put","x-module":"absences","x-access":"student","parameters":[{"name":"entity","in":"path","required":true,"schema":{"type":"string","description":"student ID"},"description":"student ID"},{"name":"absenceid","in":"path","required":true,"schema":{"type":"string","description":"absence ID"},"description":"absence ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"status":{"$ref":"#/components/schemas/AbsenceStudentStatus"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/absences/lessons/{entities}/{datesrange}":{"get":{"tags":["Absences"],"summary":"Get lessons impacted by absences over a date range","description":"`os_absences_lessons_get` · minimal role **admin**\n\nGet lessons impacted by absences over a date range","operationId":"os_absences_lessons_get","x-module":"absences","x-access":"admin","parameters":[{"name":"entities","in":"path","required":true,"schema":{"type":"string","description":"type of entity: teachers, classes or students","enum":["teachers","classes","students"]},"description":"type of entity: teachers, classes or students"},{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"otherabsences":{"description":"List of other absences on the date range that could have an impact on lessons","type":"object","properties":{"teachers":{"description":"List of teacher absences, by teacher ID, by absence ID","type":"object","additionalProperties":{"description":"List of absences of a specific teacher","type":"object","additionalProperties":{"$ref":"#/components/schemas/AbsenceTeacher"}}},"classes":{"description":"List of class absences","type":"object","additionalProperties":{"description":"List of absences of a specific class","type":"object","additionalProperties":{"$ref":"#/components/schemas/AbsenceClass"}}}}},"lessons":{"description":"List of lessons impacted by absences","type":"array","items":{"$ref":"#/components/schemas/LessonSchedule"}},"timetables":{"description":"List of timetables for the lessons","type":"array","items":{"$ref":"#/components/schemas/Timetable"}}}}}}}}}},"/api/staffing/grids":{"get":{"tags":["Staffing"],"summary":"List all staffing grids (versioned)","description":"`os_staffing_grids_get` · minimal role **staff**\n\nList all staffing grids (versioned)","operationId":"os_staffing_grids_get","x-module":"staffing","x-access":"staff","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"grids":{"$ref":"#/components/schemas/StaffingGrids"},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}}}}}}},"post":{"tags":["Staffing"],"summary":"Create a new grid","description":"`os_staffing_grids_post` · minimal role **admin**\n\nCreate a new grid","operationId":"os_staffing_grids_post","x-module":"staffing","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffingGrid"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"gridid":{"type":"string"},"grid":{"$ref":"#/components/schemas/StaffingGrid"}}}}}}}},"put":{"tags":["Staffing"],"summary":"Assign date ranges to grids (exclusive). Use 'dates' map with arrays of [YYYY-MM-DD, YYYY-MM-DD] inclusive.","description":"`os_staffing_grids_put` · minimal role **admin**\n\nAssign date ranges to grids (exclusive). Use 'dates' map with arrays of [YYYY-MM-DD, YYYY-MM-DD] inclusive.","operationId":"os_staffing_grids_put","x-module":"staffing","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"dates":{"type":"object","additionalProperties":{"type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":{"type":"string","format":"date"}}}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/staffing/grids/{gridid}":{"put":{"tags":["Staffing"],"summary":"Update a specific staffing grid","description":"`os_staffing_grids-grid_put` · minimal role **admin**\n\nUpdate a specific staffing grid","operationId":"os_staffing_grids-grid_put","x-module":"staffing","x-access":"admin","parameters":[{"name":"gridid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffingGrid"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"grid":{"$ref":"#/components/schemas/StaffingGrid"}}}}}}}},"delete":{"tags":["Staffing"],"summary":"Delete a staffing grid (only if no dates assigned)","description":"`os_staffing_grids_delete` · minimal role **admin**\n\nDelete a staffing grid (only if no dates assigned)","operationId":"os_staffing_grids_delete","x-module":"staffing","x-access":"admin","parameters":[{"name":"gridid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/staffing/sites":{"get":{"tags":["Staffing"],"summary":"List all staffing sites","description":"`os_staffing_sites_get` · minimal role **staff**\n\nList all staffing sites","operationId":"os_staffing_sites_get","x-module":"staffing","x-access":"staff","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"sites":{"$ref":"#/components/schemas/StaffingSites"}}}}}}}},"put":{"tags":["Staffing"],"summary":"Update staffing sites","description":"`os_staffing_sites_put` · minimal role **admin**\n\nUpdate staffing sites","operationId":"os_staffing_sites_put","x-module":"staffing","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sites":{"$ref":"#/components/schemas/StaffingSites"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"sites":{"$ref":"#/components/schemas/StaffingSites"}}}}}}}}},"/api/staffing/assignments":{"get":{"tags":["Staffing"],"summary":"Get all assignments","description":"`os_staffing_assignments_get` · minimal role **staff**\n\nGet all assignments","operationId":"os_staffing_assignments_get","x-module":"staffing","x-access":"staff","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"assignments":{"$ref":"#/components/schemas/StaffingAssignments"},"display_order":{"$ref":"#/components/schemas/StaffingDisplayOrder"}}}}}}}},"post":{"tags":["Staffing"],"summary":"Create assignments (single) or import/update them in bulk","description":"`os_staffing_assignments_post` · minimal role **admin**\n\nCreate assignments (single) or import/update them in bulk","operationId":"os_staffing_assignments_post","x-module":"staffing","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"assignments":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/StaffingAssignment"},{"type":"object","properties":{"id":{"type":"string"}}}]}}},"required":["assignments"]},{"$ref":"#/components/schemas/StaffingAssignment"}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Staffing"],"summary":"Update assignments config","description":"`os_staffing_assignements-config_put` · minimal role **admin**\n\nUpdate assignments config","operationId":"os_staffing_assignements-config_put","x-module":"staffing","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"display_order":{"$ref":"#/components/schemas/StaffingDisplayOrder"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/staffing/assignments/{assignmentid}":{"put":{"tags":["Staffing"],"summary":"Update an assignment by id","description":"`os_staffing_assignments_put` · minimal role **admin**\n\nUpdate an assignment by id","operationId":"os_staffing_assignments_put","x-module":"staffing","x-access":"admin","parameters":[{"name":"assignmentid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/StaffingAssignment"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Staffing"],"summary":"Delete an assignment by id","description":"`os_staffing_assignments_delete` · minimal role **admin**\n\nDelete an assignment by id","operationId":"os_staffing_assignments_delete","x-module":"staffing","x-access":"admin","parameters":[{"name":"assignmentid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/staffing/staff":{"get":{"tags":["Staffing"],"summary":"Get all staff","description":"`os_staffing_staff_get` · minimal role **staff**\n\nGet all staff","operationId":"os_staffing_staff_get","x-module":"staffing","x-access":"staff","parameters":[{"name":"with_absences","in":"query","required":false,"schema":{"type":"boolean","description":"Include staff absences in response (absences.staff)"},"description":"Include staff absences in response (absences.staff)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"absences":{"description":"Absences of staff","type":"object","additionalProperties":{"description":"Absences for a specific staff member (by ID of staff member, then by index)","type":"object","additionalProperties":{"$ref":"#/components/schemas/AbsenceStaff"}}},"staff":{"$ref":"#/components/schemas/StaffingStaff"}}}}}}}},"post":{"tags":["Staffing"],"summary":"Create a virtual staff member","description":"`os_staffing_staff_post` · minimal role **admin**\n\nCreate a virtual staff member","operationId":"os_staffing_staff_post","x-module":"staffing","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"virtual_name":{"description":"Staff member's virtual name = a staff member not yet hired.","type":"string"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/staffing/staff/{staffid}":{"put":{"tags":["Staffing"],"summary":"Rename a virtual staff member","description":"`os_staffing_staff_put` · minimal role **admin**\n\nRename a virtual staff member","operationId":"os_staffing_staff_put","x-module":"staffing","x-access":"admin","parameters":[{"name":"staffid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"virtual_name":{"description":"Staff member's virtual name = a staff member not yet hired.","type":"string"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Staffing"],"summary":"Delete a staff member by id","description":"`os_staffing_staff_delete` · minimal role **admin**\n\nDelete a staff member by id","operationId":"os_staffing_staff_delete","x-module":"staffing","x-access":"admin","parameters":[{"name":"staffid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/staffing/schedule":{"get":{"tags":["Staffing"],"summary":"Get the full staffing schedule","description":"`os_staffing_schedule_get` · minimal role **staff**\n\nGet the full staffing schedule","operationId":"os_staffing_schedule_get","x-module":"staffing","x-access":"staff","parameters":[{"name":"with_grids","in":"query","required":false,"schema":{"type":"boolean","description":"Include grids and sites information"},"description":"Include grids and sites information"},{"name":"with_assignments","in":"query","required":false,"schema":{"type":"boolean","description":"Include assignments information"},"description":"Include assignments information"},{"name":"with_schoolyears","in":"query","required":false,"schema":{"type":"boolean","description":"Include school years information"},"description":"Include school years information"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"schedule":{"description":"Staffing schedules, by date (YYYY-MM-DD)","type":"object","additionalProperties":{"$ref":"#/components/schemas/StaffingScheduleDate"}},"grid":{"$ref":"#/components/schemas/StaffingGrid"},"assignments":{"$ref":"#/components/schemas/StaffingAssignments"},"display_order":{"$ref":"#/components/schemas/StaffingDisplayOrder"},"school_years":{"description":"School years (academic years)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"}}}}}}}},"put":{"tags":["Staffing"],"summary":"Update the full staffing schedule","description":"`os_staffing_schedule_put` · minimal role **admin**\n\nUpdate the full staffing schedule","operationId":"os_staffing_schedule_put","x-module":"staffing","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schedule":{"description":"Staffing schedules, by date (YYYY-MM-DD)","type":"object","additionalProperties":{"$ref":"#/components/schemas/StaffingScheduleDate"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/staffing/schedule/{datesrange}":{"delete":{"tags":["Staffing"],"summary":"Delete staffing schedule entries for a specific date range","description":"`os_staffing_schedule_delete` · minimal role **admin**\n\nDelete staffing schedule entries for a specific date range","operationId":"os_staffing_schedule_delete","x-module":"staffing","x-access":"admin","parameters":[{"name":"datesrange","in":"path","required":true,"schema":{"type":"string","description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","oneOf":[{"pattern":"^-?$","description":"All dates (e.g., \"\", \"-\")","type":"string"},{"pattern":"^\\d{8}-\\d{8}$","description":"Date interval in the format YYYYMMDD-YYYYMMDD","type":"string"},{"pattern":"^\\d{8}-$","description":"Date interval with only a start date specified (YYYYMMDD-)","type":"string"},{"pattern":"^-\\d{8}$","description":"Date interval with only an end date specified (-YYYYMMDD)","type":"string"},{"pattern":"^\\d{8}$","description":"Single date in the format YYYYMMDD","type":"string"},{"pattern":"^\\d{8}(-\\d{8})?(,\\d{8}(-\\d{8})?)+$","description":"Sparse closed date segments, e.g. YYYYMMDD,YYYYMMDD-YYYYMMDD,YYYYMMDD","type":"string"}]},"description":"Date range in format [YYYYMMDD][-][YYYYMMDD], e.g. \"20250901-20260731\" for the 2025-2026 school year. Use \"\" or \"-\" for all dates. Closed segments can be comma-separated to request sparse dates.","examples":{"fullRange":{"summary":"Date range <begin>-<end>","value":"20240912-20240919"},"singleDate":{"summary":"Date for one specific day","value":"20250329"},"allRange":{"summary":"Beginning of times to the end of times","value":"-"},"openEnded":{"summary":"All date from day to the end of times","value":"20240912-"},"sparseRange":{"summary":"Specific days and closed intervals","value":"20240912,20240916-20240918,20240923"}}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables":{"get":{"tags":["Timetables"],"summary":"List the account's timetables — each with its label, type (calendar or week), cycle, active/published status, school year, and class/teacher/course counts. Use this to list, count, or summarize timetables and their types/status.","description":"`os_timetables_get` · minimal role **teacher**\n\nList the account's timetables — each with its label, type (calendar or week), cycle, active/published status, school year, and class/teacher/course counts. Use this to list, count, or summarize timetables and their types/status.","operationId":"os_timetables_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"schoolyear","in":"query","required":false,"schema":{"type":"string","description":"School year ID (optional, default = current, special values: '_all', '_current')"},"description":"School year ID (optional, default = current, special values: '_all', '_current')"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"timetables":{"type":"object","additionalProperties":{"date_creation":{"type":"string","description":"Date-time value used in timetable metadata. Canonical format is ISO 8601 UTC; legacy format is still accepted during migration.","oneOf":[{"description":"Legacy format kept for backward compatibility (YYYY-MM-DD HH:MM:SS with optional AM/PM).","pattern":"^\\d{4}-\\d{2}-\\d{2} \\d{1,2}:\\d{2}:\\d{2}(?: AM| PM)?$","examples":[],"type":"string"},{"format":"date-time","description":"ISO 8601 format. Canonical storage should be UTC (`Z`).","examples":[],"type":"string"}]},"date_generation":{"type":"string","description":"Date-time value used in timetable metadata. Canonical format is ISO 8601 UTC; legacy format is still accepted during migration.","oneOf":[{"description":"Legacy format kept for backward compatibility (YYYY-MM-DD HH:MM:SS with optional AM/PM).","pattern":"^\\d{4}-\\d{2}-\\d{2} \\d{1,2}:\\d{2}:\\d{2}(?: AM| PM)?$","examples":[],"type":"string"},{"format":"date-time","description":"ISO 8601 format. Canonical storage should be UTC (`Z`).","examples":[],"type":"string"}]},"date_update":{"type":"string","description":"Date-time value used in timetable metadata. Canonical format is ISO 8601 UTC; legacy format is still accepted during migration.","oneOf":[{"description":"Legacy format kept for backward compatibility (YYYY-MM-DD HH:MM:SS with optional AM/PM).","pattern":"^\\d{4}-\\d{2}-\\d{2} \\d{1,2}:\\d{2}:\\d{2}(?: AM| PM)?$","examples":[],"type":"string"},{"format":"date-time","description":"ISO 8601 format. Canonical storage should be UTC (`Z`).","examples":[],"type":"string"}]},"label":{"description":"Label","type":"string"},"description":{"description":"Description","type":"string"},"active":{"description":"Is this timetable activated/published?","type":"boolean"},"type":{"description":"Type of timetable. \"Week\": weekly schedule repeated over time. \"cycle\": multi-day cycle (e.g. 6-day rotating schedule), \"calendar\": individual dates are scheduled explicitly, with no repeating pattern","type":"string","enum":["week","cycle","calendar"],"default":"week"},"cycle":{"description":"Number of the multi-day cycle (if type = cycle)","type":"integer"},"dates":{"description":"Start/end dates (if type = calendar)","type":"array","minItems":2,"maxItems":2,"examples":[],"items":{"type":"string","format":"date"}},"weeks":{"type":"array","items":{"type":"object","description":"Week range in number since EPOCH","properties":{"begin":{"type":"integer"},"end":{"type":"integer"}},"required":["begin","end"]}},"nbclasses":{"type":"integer","description":"Number of classes"},"nbteachers":{"type":"integer","description":"Number of teachers"},"nbcourses":{"type":"integer","description":"Number of courses"},"color":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}},"school_years":{"description":"School years (academic years)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"firstday":{"description":"First day of the week, 0 = Sunday, 1 = Monday","type":"integer","enum":[0,1],"default":1},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}}}}}}},"post":{"tags":["Timetables"],"summary":"Create a new timetable","description":"`os_timetables_post` · minimal role **admin**\n\nCreate a new timetable","operationId":"os_timetables_post","x-module":"timetables","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Timetables"],"summary":"Activate/publish timetables","description":"`os_timetables_put` · minimal role **admin**\n\nActivate/publish timetables","operationId":"os_timetables_put","x-module":"timetables","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}":{"get":{"tags":["Timetables"],"summary":"Retrieve a specific timetable by its ID","description":"`os_timetables-timetable_get` · minimal role **teacher**\n\nRetrieve a specific timetable by its ID","operationId":"os_timetables-timetable_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"with_teachers_subjects","in":"query","required":false,"schema":{"type":"boolean","description":"Consolidate all subjects taught by each teacher"},"description":"Consolidate all subjects taught by each teacher"},{"name":"with_infos","in":"query","required":false,"schema":{"type":"boolean","description":"Include additional teacher information (gender, email, etc.), only if admin"},"description":"Include additional teacher information (gender, email, etc.), only if admin"},{"name":"with_events","in":"query","required":false,"schema":{"type":"boolean","description":"Include custom events if timetable is a calendar"},"description":"Include custom events if timetable is a calendar"},{"name":"with_useroptions","in":"query","required":false,"schema":{"type":"boolean","description":"Include schedules_options (custom sessions, restore flag) for the current admin user"},"description":"Include schedules_options (custom sessions, restore flag) for the current admin user"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"timetable":{"$ref":"#/components/schemas/Timetable"},"levels":{"type":"array","items":{"type":"string"}},"campuses":{"description":"Configured campus labels","type":"array","x-premiumOnly":true,"items":{"type":"string"}},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"firstday":{"description":"First day of the week, 0 = Sunday, 1 = Monday","type":"integer","enum":[0,1],"default":1},"weekalt":{"description":"Support for alternate weeks","type":"string","enum":["numbers","letters","no"],"default":"numbers"},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}}}}}}},"put":{"tags":["Timetables"],"summary":"Update lessons in a specific timetable by its ID","description":"`os_timetables-timetable_put` · minimal role **admin**\n\nUpdate lessons in a specific timetable by its ID","operationId":"os_timetables-timetable_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"Timetable ID"},"description":"Timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"$ref":"#/components/schemas/Alterations"},{"type":"object","properties":{"timetable":{"allOf":[{"$ref":"#/components/schemas/Timetable"},{"description":"Complete timetable to merge"}]}}}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"revisions":{"description":"New _osrev values per course ID (for identity-based updates)","type":"object","additionalProperties":{"type":"string"}},"merged":{"description":"Auto-merged courses (backend resolved conflicts)","type":"object","additionalProperties":{"$ref":"#/components/schemas/LessonClass"}},"ignored":{"description":"Courses that couldn't be stored (malformed, missing class, invalid _id, etc.)","type":"array","items":{"type":"object","properties":{"course":{"$ref":"#/components/schemas/LessonClass"},"reason":{"type":"string","enum":["no_target","invalid_id"]}}}}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete a specific timetable by its ID","description":"`os_timetables-timetable_delete` · minimal role **admin**\n\nDelete a specific timetable by its ID","operationId":"os_timetables-timetable_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/json":{"get":{"tags":["Timetables"],"summary":"Retrieve a specific timetable in JSON format (if calendar type, then merge all teacher wishes)","description":"`os_timetables_json_get` · minimal role **admin**\n\nRetrieve a specific timetable in JSON format (if calendar type, then merge all teacher wishes)","operationId":"os_timetables_json_get","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"data":{"allOf":[{"$ref":"#/components/schemas/Timetable"},{"description":"Timetable in JSON format"}]}}}}}}}}},"/api/timetables/{timetableid}/import":{"put":{"tags":["Timetables"],"summary":"Import data (coming from a parsed table of lessons in frontend) into a specific timetable","description":"`os_timetables_import_put` · minimal role **admin**\n\nImport data (coming from a parsed table of lessons in frontend) into a specific timetable","operationId":"os_timetables_import_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"timetable":{"$ref":"#/components/schemas/Timetable"},"newentities":{"type":"object","properties":{"subjects":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/SubjectFull"}},"types":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string"},"code":{"type":"string"},"color":{"type":"string"}}}},"classes":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClass"}},"teachers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableTeacher"}},"groups":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClassGroup"}},"groupsets":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableGroupGroupset"}},"sites":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableSite"}},"classrooms":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClassroom"}},"resources":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableResource"}}}},"test":{"type":"boolean"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/tweaks":{"put":{"tags":["Timetables"],"summary":"Update automatic generation algorithm options/tweaks","description":"`os_timetables_tweaks_put` · minimal role **admin**\n\nUpdate automatic generation algorithm options/tweaks","operationId":"os_timetables_tweaks_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"tweaks":{"$ref":"#/components/schemas/TimetableGenerationTweaks"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/generation":{"post":{"tags":["Timetables"],"summary":"Launch the automatic generation process for a specific timetable","description":"`os_timetables_generation_post` · minimal role **admin**\n\nLaunch the automatic generation process for a specific timetable","operationId":"os_timetables_generation_post","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"action":{"type":"string","enum":["abort"],"description":"Action to perform (abort: cancel a running generation)"},"tweaks":{"$ref":"#/components/schemas/TimetableGenerationTweaks"},"extratweaks":{"type":"object","description":"Temporary/extra tweaks for this generation only (not saved)","properties":{"classrooms":{"type":"string","enum":["full","check-only","ignore"],"description":"Classroom assignment mode"},"onlyclasses":{"type":"array","items":{"type":"string"},"description":"Array of class IDs to generate (whitelist)"},"onlysubjects":{"type":"array","items":{"type":"string"},"description":"Array of subject IDs to generate (whitelist)"},"dates":{"type":"array","items":{"type":"string","format":"date"},"minItems":2,"maxItems":2,"description":"Date range [begin, end] to generate for calendar timetables"}}},"cross":{"type":"object","description":"Cross-timetable unavailability consolidation for this generation only: occupations of the selected peers become mandatory unavailabilities in the solver input","properties":{"timetables":{"type":"array","items":{"type":"string"},"description":"Active same-account timetable IDs to consolidate"},"schools":{"type":"array","items":{"type":"string"},"description":"Linked account IDs whose operational occupations are consolidated"}}},"extraargs":{"type":"array","items":{"type":"string","enum":["args_flexibleslots","args_classrooms_ignore","args_positions_ignore","args_action_classrooms","args_action_verify"]},"description":"Extra arguments flags for the generation algorithm"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete the automatic generation result for a specific timetable","description":"`os_timetables_generation_delete` · minimal role **admin**\n\nDelete the automatic generation result for a specific timetable","operationId":"os_timetables_generation_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"get":{"tags":["Timetables"],"summary":"Retrieve the result of the automatic generation for a specific timetable","description":"`os_timetables_generation_get` · minimal role **admin**\n\nRetrieve the result of the automatic generation for a specific timetable","operationId":"os_timetables_generation_get","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/config":{"get":{"tags":["Timetables"],"summary":"Retrieve the configuration of a specific timetable","description":"`os_timetables_config_get` · minimal role **teacher**\n\nRetrieve the configuration of a specific timetable","operationId":"os_timetables_config_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"config":{"$ref":"#/components/schemas/TimetableConfig"},"result":{"type":"boolean","description":"Whether the timetable has been generated"},"hascourses":{"type":"boolean","description":"Whether the timetable has courses defined"},"activation":{"oneOf":[{"type":"boolean"},{"type":"object"}],"description":"Activation status of the timetable"},"active":{"type":"boolean","description":"Whether the timetable is currently active"}}}}}}}},"put":{"tags":["Timetables"],"summary":"Update the configuration of a specific timetable","description":"`os_timetables_config_put` · minimal role **admin**\n\nUpdate the configuration of a specific timetable","operationId":"os_timetables_config_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimetableConfig"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"patch":{"tags":["Timetables"],"summary":"Partially update the configuration of a specific timetable (merge only provided fields)","description":"`os_timetables_config_patch` · minimal role **admin**\n\nPartially update the configuration of a specific timetable (merge only provided fields)","operationId":"os_timetables_config_patch","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":"Partial configuration object. Only provided fields will be updated, others remain unchanged.","type":"object","properties":{"label":{"description":"Label","type":"string"},"description":{"description":"Description","type":"string"},"time_period":{"description":"Time slot duration (most of the time 60 = 1 hour)","type":"integer","default":60},"time_unit":{"description":"Division of the time slot (e.g. 2 with a time_period of 60 enables lessons of 1h30","type":"integer","default":1},"colors":{"description":"Colors of the different entities","type":"object","properties":{"classes":{"description":"Colors of classes","type":"object","additionalProperties":{"type":"string"}},"subjects":{"description":"Colors of subjects","type":"object","additionalProperties":{"type":"string"}}}},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"displaymode":{"description":"Defines how the timetable grid is structured in the calendar view. \"hours\": real start/end times (e.g. 09:15–10:10), \"periods\": numbered slots (e.g. 0, 1, 2...), \"agenda\": fixed hourly layout (e.g. 8:00, 9:00, 10:00...), like in calendar apps","type":"string","enum":["hours","periods","agenda"],"default":"hours"},"type":{"description":"Type of timetable. \"Week\": weekly schedule repeated over time. \"cycle\": multi-day cycle (e.g. 6-day rotating schedule), \"calendar\": individual dates are scheduled explicitly, with no repeating pattern","type":"string","enum":["week","cycle","calendar"],"default":"week"},"cycle":{"description":"Number of the multi-day cycle (if type = cycle)","type":"integer"},"dates":{"description":"Start/end dates (if type = calendar)","type":"array","items":{"type":"string","format":"date"},"minItems":2,"maxItems":2,"examples":[]},"date_windows":{"description":"Date windows (time constraints for timetable generation). Only valid when type is 'calendar'","type":"object","additionalProperties":{"$ref":"#/components/schemas/DateWindow"},"x-dependsOn":{"type":"calendar"}},"tweaks":{"$ref":"#/components/schemas/TimetableGenerationTweaks"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/sites":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of sites associated with a specific timetable","description":"`os_timetables_sites_get` · minimal role **teacher**\n\nRetrieve the list of sites associated with a specific timetable","operationId":"os_timetables_sites_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"sites":{"type":"object","additionalProperties":{"type":"object","properties":{"name":{"type":"string","description":"Site name"},"id":{"type":"string","description":"Site ID"},"nb_classrooms":{"type":"integer","description":"Number of classrooms in this site"},"nb_resources":{"type":"integer","description":"Number of resources in this site (optional)"}},"required":["name","id","nb_classrooms"]}},"config":{"type":"object","description":"Excerpt of timetable configuration for sites UI","properties":{"type":{"description":"Type of timetable. \"Week\": weekly schedule repeated over time. \"cycle\": multi-day cycle (e.g. 6-day rotating schedule), \"calendar\": individual dates are scheduled explicitly, with no repeating pattern","type":"string","enum":["week","cycle","calendar"],"default":"week"},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"time_unit":{"description":"Division of the time slot (e.g. 2 with a time_period of 60 enables lessons of 1h30","type":"integer","default":1},"time_period":{"description":"Time slot duration (most of the time 60 = 1 hour)","type":"integer","default":60}}},"timetablesnb":{"type":"integer","description":"Total number of timetables"}}}}}}}},"post":{"tags":["Timetables"],"summary":"Create a new site for a specific timetable. Can include embedded classrooms and resources in the payload.","description":"`os_timetables_sites_post` · minimal role **admin**\n\nCreate a new site for a specific timetable. Can include embedded classrooms and resources in the payload.","operationId":"os_timetables_sites_post","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimetableSite"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Timetables"],"summary":"Update the distances between sites of a specific timetable","description":"`os_timetables_sites_distances_put` · minimal role **admin**\n\nUpdate the distances between sites of a specific timetable","operationId":"os_timetables_sites_distances_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimetableSite"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/sites/{siteid}":{"get":{"tags":["Timetables"],"summary":"Retrieve a specific site of a timetable by its ID","description":"`os_timetables_sites-site_get` · minimal role **teacher**\n\nRetrieve a specific site of a timetable by its ID","operationId":"os_timetables_sites-site_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"config":{"type":"object","description":"Excerpt of timetable configuration for sites UI","properties":{"type":{"description":"Type of timetable. \"Week\": weekly schedule repeated over time. \"cycle\": multi-day cycle (e.g. 6-day rotating schedule), \"calendar\": individual dates are scheduled explicitly, with no repeating pattern","type":"string","enum":["week","cycle","calendar"],"default":"week"},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"time_unit":{"description":"Division of the time slot (e.g. 2 with a time_period of 60 enables lessons of 1h30","type":"integer","default":1},"time_period":{"description":"Time slot duration (most of the time 60 = 1 hour)","type":"integer","default":60}}},"site":{"allOf":[{"$ref":"#/components/schemas/TimetableSite"},{"properties":{"id":{"type":"string"}},"not":{"properties":{"classrooms":{},"resources":{}}}}]},"sites":{"type":"object","additionalProperties":{"type":"string"},"description":"All sites mapping (ID -> name)"}}}}}}}},"put":{"tags":["Timetables"],"summary":"Update a specific site of a timetable by its ID","description":"`os_timetables_sites_put` · minimal role **admin**\n\nUpdate a specific site of a timetable by its ID","operationId":"os_timetables_sites_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"Name of the site","type":"string"},"hours":{"$ref":"#/components/schemas/TimetableSiteHours"},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"patch":{"tags":["Timetables"],"summary":"Patch a specific site of a timetable by its ID (null = remove field)","description":"`os_timetables_sites_patch` · minimal role **admin**\n\nPatch a specific site of a timetable by its ID (null = remove field)","operationId":"os_timetables_sites_patch","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"type":["string","null"]},"hours":{"oneOf":[{"$ref":"#/components/schemas/TimetableSiteHours"},{"type":"null"}]},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete a specific site of a timetable by its ID","description":"`os_timetables_sites_delete` · minimal role **admin**\n\nDelete a specific site of a timetable by its ID","operationId":"os_timetables_sites_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/sites/{siteid}/resources":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of resources associated with a specific site of a timetable","description":"`os_timetables_sites-resources_get` · minimal role **teacher**\n\nRetrieve the list of resources associated with a specific site of a timetable","operationId":"os_timetables_sites-resources_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"resources":{"type":"object","additionalProperties":{"allOf":[{"$ref":"#/components/schemas/TimetableResource"},{"properties":{"id":{"type":"string"}}}]}},"site":{"type":"object","properties":{"name":{"description":"Name of the site","type":"string"},"id":{"type":"string"}}},"schoolyears":{"description":"School years (academic years) (only for calendar type timetables)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}},"sites":{"type":"object","additionalProperties":{"type":"string"},"description":"Sites mapping (ID -> name)"}}}}}}}},"post":{"tags":["Timetables"],"summary":"Add a resource to a specific site of a timetable.","description":"`os_timetables_sites-resources_post` · minimal role **admin**\n\nAdd a resource to a specific site of a timetable.","operationId":"os_timetables_sites-resources_post","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"},{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimetableResource"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/sites/{siteid}/resources/{resourceid}":{"put":{"tags":["Timetables"],"summary":"Update a specific resource of a site in a timetable","description":"`os_timetables_sites-resources_put` · minimal role **admin**\n\nUpdate a specific resource of a site in a timetable","operationId":"os_timetables_sites-resources_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"},{"name":"resourceid","in":"path","required":true,"schema":{"type":"string","description":"resource ID"},"description":"resource ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimetableResource"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"patch":{"tags":["Timetables"],"summary":"Patch a specific resource of a site in a timetable (null = remove field)","description":"`os_timetables_sites-resources_patch` · minimal role **admin**\n\nPatch a specific resource of a site in a timetable (null = remove field)","operationId":"os_timetables_sites-resources_patch","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"},{"name":"resourceid","in":"path","required":true,"schema":{"type":"string","description":"resource ID"},"description":"resource ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":"Partial resource object. Only provided fields are modified; null removes a field.","type":"object","properties":{"name":{"description":"Name of the resource","type":"string"},"number":{"description":"How many of this resource","type":"integer"},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete a specific resource of a site in a timetable","description":"`os_timetables_sites-resources_delete` · minimal role **admin**\n\nDelete a specific resource of a site in a timetable","operationId":"os_timetables_sites-resources_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"},{"name":"resourceid","in":"path","required":true,"schema":{"type":"string","description":"resource ID"},"description":"resource ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/sites/{siteid}/classrooms":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of classrooms associated with a specific site of a timetable","description":"`os_timetables_sites-classrooms_get` · minimal role **teacher**\n\nRetrieve the list of classrooms associated with a specific site of a timetable","operationId":"os_timetables_sites-classrooms_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"classrooms":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClassroom"}},"site":{"allOf":[{"$ref":"#/components/schemas/TimetableSite"},{"properties":{"id":{"type":"string"}}}]},"specialisations":{"type":"array","description":"List of all specializations from all classrooms","items":{"type":"string"}},"buildings":{"type":"array","description":"List of all buildings from this site","items":{"type":"string"}}}}}}}}},"post":{"tags":["Timetables"],"summary":"Add a classroom to a specific site of a timetable (incremental by default, set replace:true for full replacement)","description":"`os_timetables_sites-classrooms_post` · minimal role **admin**\n\nAdd a classroom to a specific site of a timetable (incremental by default, set replace:true for full replacement)","operationId":"os_timetables_sites-classrooms_post","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"},{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"classrooms":{"type":"array","items":{"allOf":[{"$ref":"#/components/schemas/TimetableClassroom"},{"type":"object","properties":{"id":{"type":"string"}}}]}},"replace":{"type":"boolean","default":false,"description":"If true, replaces all existing entities. If false/omitted, merges with existing (incremental)."},"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}},"required":["classrooms"]},{"$ref":"#/components/schemas/TimetableClassroom"}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/sites/{siteid}/classrooms/{classroomid}":{"put":{"tags":["Timetables"],"summary":"Update a specific classroom of a site in a timetable","description":"`os_timetables_sites-classrooms_put` · minimal role **admin**\n\nUpdate a specific classroom of a site in a timetable","operationId":"os_timetables_sites-classrooms_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"},{"name":"classroomid","in":"path","required":true,"schema":{"type":"string","description":"classroom ID"},"description":"classroom ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimetableClassroom"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"patch":{"tags":["Timetables"],"summary":"Patch a specific classroom of a site in a timetable (null = remove field)  ","description":"`os_timetables_sites-classrooms_patch` · minimal role **admin**\n\nPatch a specific classroom of a site in a timetable (null = remove field)  ","operationId":"os_timetables_sites-classrooms_patch","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"},{"name":"classroomid","in":"path","required":true,"schema":{"type":"string","description":"classroom ID"},"description":"classroom ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":"Partial classroom object. Only provided fields are modified; null removes a field.","type":"object","properties":{"name":{"description":"Name of the classroom","type":"string"},"capacity":{"description":"Capacity of the classroom (number of seats)","type":"integer"},"specialisation":{"description":"Specialisation of the classroom (free label). To be associated with specific subjects (e.g. stadium with PE)","type":"string"},"maxclasses":{"description":"Maximal number of simultaneous classes having different lessons at the same time. For example, an examination room, or a gymnasium.","type":"integer"},"building":{"description":"Building of the classroom (can also be used to specify the floor)","type":"string"},"wishes":{"allOf":[{"$ref":"#/components/schemas/Wishes"},{"description":"Specific slots when the classroom is available"}]},"description":{"description":"Description of the room","type":"string"},"tags":{"description":"Different tags","type":"array","items":{"type":"string"}},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete a specific classroom of a site in a timetable","description":"`os_timetables_sites-classrooms_delete` · minimal role **admin**\n\nDelete a specific classroom of a site in a timetable","operationId":"os_timetables_sites-classrooms_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"siteid","in":"path","required":true,"schema":{"type":"string","description":"site ID"},"description":"site ID"},{"name":"classroomid","in":"path","required":true,"schema":{"type":"string","description":"classroom ID"},"description":"classroom ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classrooms":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of classrooms associated with a specific timetable","description":"`os_timetables_classrooms_get` · minimal role **teacher**\n\nRetrieve the list of classrooms associated with a specific timetable","operationId":"os_timetables_classrooms_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"sites":{"type":"object","additionalProperties":{"type":"object","properties":{"id":{"type":"string"},"name":{"description":"Name of the site","type":"string"},"classrooms":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClassroom"}}}}},"schoolyears":{"description":"School years (academic years) (only for calendar type timetables)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}}}}}}}}}},"/api/timetables/{timetableid}/teachers":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of teachers associated with a specific timetable","description":"`os_timetables_teachers_get` · minimal role **teacher**\n\nRetrieve the list of teachers associated with a specific timetable","operationId":"os_timetables_teachers_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"with_config","in":"query","required":false,"schema":{"type":"boolean","description":"Include timetable configuration (time_period, time_unit, weekdays)"},"description":"Include timetable configuration (time_period, time_unit, weekdays)"},{"name":"with_sites","in":"query","required":false,"schema":{"type":"boolean","description":"Include sites information (hours only)"},"description":"Include sites information (hours only)"},{"name":"with_subjects","in":"query","required":false,"schema":{"type":"boolean","description":"Include subjects taught by teachers"},"description":"Include subjects taught by teachers"},{"name":"with_infos","in":"query","required":false,"schema":{"type":"boolean","description":"Include additional teacher information (gender, email, etc.), only if admin"},"description":"Include additional teacher information (gender, email, etc.), only if admin"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"teachers":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableTeacher"}},"config":{"allOf":[{"$ref":"#/components/schemas/TimetableConfig"},{"description":"Timetable configuration (if with_config=true)"}]},"sites":{"allOf":[{"$ref":"#/components/schemas/TimetableSite"},{"not":{"properties":{"classrooms":{},"distances":{},"resources":{}}}}],"description":"Sites with classrooms, distances, and resources removed (if with_sites=true)"},"shadow_wishes":{"type":"boolean","description":"Indicates shadow wishes mode for calendar timetables"}}}}}}}},"post":{"tags":["Timetables"],"summary":"Add/import teachers to a specific timetable. Can be a virtual teacher (creation) or an importation from admin, reinjected by frontend","description":"`os_timetables_teachers_post` · minimal role **admin**\n\nAdd/import teachers to a specific timetable. Can be a virtual teacher (creation) or an importation from admin, reinjected by frontend","operationId":"os_timetables_teachers_post","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"teachers":{"type":"array","items":{"$ref":"#/components/schemas/TimetableTeacher"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"teachers":{"type":"array","items":{"type":"string"},"description":"Array of created teacher IDs"}}}}}}}}},"/api/timetables/{timetableid}/teachers/{teacherid}":{"get":{"tags":["Timetables"],"summary":"Retrieve a specific teacher of a timetable by their ID","description":"`os_timetables_teachers-teacher_get` · minimal role **admin**\n\nRetrieve a specific teacher of a timetable by their ID","operationId":"os_timetables_teachers-teacher_get","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"teachers":{"allOf":[{"$ref":"#/components/schemas/TimetableTeacher"},{"properties":{"userwishes":{"type":"object","description":"Teacher wishes (for non-calendar timetables)"}}}]}}}}}}}},"put":{"tags":["Timetables"],"summary":"Update a specific teacher of a timetable: edit virtual name, or transform a teacher to another one","description":"`os_timetables_teachers_put` · minimal role **admin**\n\nUpdate a specific teacher of a timetable: edit virtual name, or transform a teacher to another one","operationId":"os_timetables_teachers_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"shiftid":{"type":"string","description":"Transfer teacher to another user ID"}}},{"type":"object","properties":{"virtual_name":{"description":"Virtual teacher name representing a generic role for a teacher not yet hired, e.g., \"math teacher\".","type":"string"},"subjects":{"description":"Subjects taught by the virtual teacher","type":"array","items":{"description":"Subject ID","type":"string"}}}}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"userwishes":{"type":"object","description":"Wishes/preferences/availabilities of the teacher","properties":{"hours":{"description":"Specific rules on hours for availabilities","type":"array","items":{"description":"Time span with associated rule for availability/wish/preference","type":"object","required":["day","priority"],"oneOf":[{"properties":{"period_begin":{"not":{"anyOf":[{}]}},"period_end":{"not":{"anyOf":[{}]}},"begin":{"not":{"anyOf":[{}]}},"end":{"not":{"anyOf":[{}]}}},"type":"object"},{"anyOf":[{"required":["period_begin"],"type":"object"},{"required":["period_end"],"type":"object"}],"properties":{"begin":{"not":{"anyOf":[{}]}},"end":{"not":{"anyOf":[{}]}}},"type":"object"},{"anyOf":[{"required":["begin"],"type":"object"},{"required":["end"],"type":"object"}],"properties":{"period_begin":{"not":{"anyOf":[{}]}},"period_end":{"not":{"anyOf":[{}]}}},"type":"object"}],"properties":{"day":{"description":"Day, date or cycle day. If no time bound is provided, the wish applies to the whole day.","type":"string","oneOf":[{"format":"date","type":"string"},{"enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"type":"string"},{"pattern":"^[0-9]+$","type":"string"}]},"school_year":{"description":"Optional school year scope for recurring non-dated wishes in calendar mode.","type":"string"},"period_begin":{"description":"Start in period number (exclusive to minute bounds). If omitted while period_end is present, the span starts at the beginning of the day.","type":"integer"},"period_end":{"description":"End in period number (exclusive to minute bounds). This bound is *excluded*, meaning the span is [period_begin, period_end[. If omitted while period_begin is present, the span ends at the end of the day.","type":"integer"},"begin":{"description":"Start in minutes (exclusive to period bounds). If omitted while end is present, the span starts at the beginning of the day.","type":"integer"},"end":{"description":"End in minutes (exclusive to period bounds). If omitted while begin is present, the span ends at the end of the day.","type":"integer"},"priority":{"description":"Priority associated to the rule. \"mandatory\" is *strong* (must ABSOLUTELY be avoided), \"high\" may be strongly avoided if possible, \"medium\" is not preferred, \"preferred\" is positive preference, and \"none\" explicitly erases the effect of previous wishes on the covered span. \"custom\" is a frontend-only intermediate state and is not persisted in Wishes storage.","type":"string","enum":["mandatory","high","medium","preferred","none"]},"sites":{"description":"Optional sites the wishes are referring to","type":"array","items":{"type":"string"}}}}},"time_unit":{"description":"If it is in period number, what is the time unit as in the grid","type":"number","default":1},"time_period":{"description":"If it is in period number, what is the time period as in the grid","type":"number","default":60},"maxhours":{"description":"Maximum number of lesson hours per day (format \"HH:MM\" preferred, integer hours accepted)","oneOf":[{"type":"string","pattern":"^[0-9]{1,3}:[0-5][0-9]$"},{"type":"integer","minimum":0}],"examples":[]},"maxhoursweek":{"description":"Maximum number of lesson hours per week (format \"HH:MM\" preferred, integer hours accepted)","oneOf":[{"type":"string","pattern":"^[0-9]{1,3}:[0-5][0-9]$"},{"type":"integer","minimum":0}],"examples":[]},"comment":{"description":"Free comment, for example to be used by teachers to communicate specific remarks on their wishes","type":"string"},"date_windows":{"description":"Optional array of date window IDs (slugs) to constrain when lessons can be scheduled. Only valid for calendar timetables","type":"array","items":{"type":"string"}},"priority":{"description":"What is the priority of this wish compared to other wishes (low, normal or high)","type":"string","enum":["low","normal","high"],"default":"normal"},"consecutivedaysmin":{"description":"Number of minimum consecutive days with lessons","type":"number"},"consecutivedaysmax":{"description":"Number of maximum consecutive days with lessons","type":"number"}}},"id":{"type":"string","description":"ID of the updated teacher"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete a specific teacher of a timetable","description":"`os_timetables_teachers_delete` · minimal role **admin**\n\nDelete a specific teacher of a timetable","operationId":"os_timetables_teachers_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/teachers/{teacherid}/hours":{"put":{"tags":["Timetables"],"summary":"Update the working hours of a specific teacher in a timetable","description":"`os_timetables_teachers-hours_put` · minimal role **admin**\n\nUpdate the working hours of a specific teacher in a timetable","operationId":"os_timetables_teachers-hours_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"servicehours":{"description":"Service hours, i.e. the number of hours the teacher should give on this timetable","type":"integer"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete the working hours of a specific teacher in a timetable","description":"`os_timetables_teachers-hours_delete` · minimal role **admin**\n\nDelete the working hours of a specific teacher in a timetable","operationId":"os_timetables_teachers-hours_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/teachers/{teacherid}/classroom":{"put":{"tags":["Timetables"],"summary":"Assign a preferred classroom to a specific teacher in a timetable","description":"`os_timetables_teachers-classroom_put` · minimal role **admin**\n\nAssign a preferred classroom to a specific teacher in a timetable","operationId":"os_timetables_teachers-classroom_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"classroom":{"description":"Preferred room for the teacher (format <siteid>:<classroomid>)","type":"string"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete the classroom preference for a specific teacher in a timetable","description":"`os_timetables_teachers-classroom_delete` · minimal role **admin**\n\nDelete the classroom preference for a specific teacher in a timetable","operationId":"os_timetables_teachers-classroom_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/teachers/{teacherid}/wishes":{"put":{"tags":["Timetables"],"summary":"Update the preferences of a specific teacher for the timetable","description":"`os_timetables_teachers-wishes_put` · minimal role **admin**\n\nUpdate the preferences of a specific teacher for the timetable","operationId":"os_timetables_teachers-wishes_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"wishes":{"type":"object","description":"Wishes/preferences/availabilities of the teacher","properties":{"hours":{"description":"Specific rules on hours for availabilities","type":"array","items":{"description":"Time span with associated rule for availability/wish/preference","type":"object","required":["day","priority"],"oneOf":[{"properties":{"period_begin":{"not":{"anyOf":[{}]}},"period_end":{"not":{"anyOf":[{}]}},"begin":{"not":{"anyOf":[{}]}},"end":{"not":{"anyOf":[{}]}}},"type":"object"},{"anyOf":[{"required":["period_begin"],"type":"object"},{"required":["period_end"],"type":"object"}],"properties":{"begin":{"not":{"anyOf":[{}]}},"end":{"not":{"anyOf":[{}]}}},"type":"object"},{"anyOf":[{"required":["begin"],"type":"object"},{"required":["end"],"type":"object"}],"properties":{"period_begin":{"not":{"anyOf":[{}]}},"period_end":{"not":{"anyOf":[{}]}}},"type":"object"}],"properties":{"day":{"description":"Day, date or cycle day. If no time bound is provided, the wish applies to the whole day.","type":"string","oneOf":[{"format":"date","type":"string"},{"enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"type":"string"},{"pattern":"^[0-9]+$","type":"string"}]},"school_year":{"description":"Optional school year scope for recurring non-dated wishes in calendar mode.","type":"string"},"period_begin":{"description":"Start in period number (exclusive to minute bounds). If omitted while period_end is present, the span starts at the beginning of the day.","type":"integer"},"period_end":{"description":"End in period number (exclusive to minute bounds). This bound is *excluded*, meaning the span is [period_begin, period_end[. If omitted while period_begin is present, the span ends at the end of the day.","type":"integer"},"begin":{"description":"Start in minutes (exclusive to period bounds). If omitted while end is present, the span starts at the beginning of the day.","type":"integer"},"end":{"description":"End in minutes (exclusive to period bounds). If omitted while begin is present, the span ends at the end of the day.","type":"integer"},"priority":{"description":"Priority associated to the rule. \"mandatory\" is *strong* (must ABSOLUTELY be avoided), \"high\" may be strongly avoided if possible, \"medium\" is not preferred, \"preferred\" is positive preference, and \"none\" explicitly erases the effect of previous wishes on the covered span. \"custom\" is a frontend-only intermediate state and is not persisted in Wishes storage.","type":"string","enum":["mandatory","high","medium","preferred","none"]},"sites":{"description":"Optional sites the wishes are referring to","type":"array","items":{"type":"string"}}}}},"time_unit":{"description":"If it is in period number, what is the time unit as in the grid","type":"number","default":1},"time_period":{"description":"If it is in period number, what is the time period as in the grid","type":"number","default":60},"maxhours":{"description":"Maximum number of lesson hours per day (format \"HH:MM\" preferred, integer hours accepted)","oneOf":[{"type":"string","pattern":"^[0-9]{1,3}:[0-5][0-9]$"},{"type":"integer","minimum":0}],"examples":[]},"maxhoursweek":{"description":"Maximum number of lesson hours per week (format \"HH:MM\" preferred, integer hours accepted)","oneOf":[{"type":"string","pattern":"^[0-9]{1,3}:[0-5][0-9]$"},{"type":"integer","minimum":0}],"examples":[]},"comment":{"description":"Free comment, for example to be used by teachers to communicate specific remarks on their wishes","type":"string"},"date_windows":{"description":"Optional array of date window IDs (slugs) to constrain when lessons can be scheduled. Only valid for calendar timetables","type":"array","items":{"type":"string"}},"priority":{"description":"What is the priority of this wish compared to other wishes (low, normal or high)","type":"string","enum":["low","normal","high"],"default":"normal"},"consecutivedaysmin":{"description":"Number of minimum consecutive days with lessons","type":"number"},"consecutivedaysmax":{"description":"Number of maximum consecutive days with lessons","type":"number"}}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of classes associated with a specific timetable (a class is a set of students attending mostly the same lessons. Synonym of class can be population, cohort, session, module)","description":"`os_timetables_classes_get` · minimal role **teacher**\n\nRetrieve the list of classes associated with a specific timetable (a class is a set of students attending mostly the same lessons. Synonym of class can be population, cohort, session, module)","operationId":"os_timetables_classes_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"classes":{"type":"object","additionalProperties":{"allOf":[{"$ref":"#/components/schemas/TimetableClassBase"},{"properties":{"id":{"type":"string"},"nb_students":{"type":"integer","description":"Number of students (if studentsonclasses config is true)"},"nb_groups":{"type":"integer","description":"Number of groups in this class"},"nb_subjects":{"type":"integer","description":"Number of subjects in this class"}}}]}},"levels":{"type":"array","items":{"type":"string"}},"campuses":{"description":"Configured campus labels","type":"array","x-premiumOnly":true,"items":{"type":"string"}},"sites":{"allOf":[{"$ref":"#/components/schemas/TimetableSite"},{"not":{"properties":{"resources":{}}}}]},"config":{"allOf":[{"$ref":"#/components/schemas/TimetableConfig"},{"not":{"properties":{"colors":{},"description":{},"label":{}}}}]},"schoolyears":{"description":"School years (academic years)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}}}}}}}}},"post":{"tags":["Timetables"],"summary":"Add a class to a specific timetable (incremental by default, set replace:true for full replacement)","description":"`os_timetables_classes_post` · minimal role **admin**\n\nAdd a class to a specific timetable (incremental by default, set replace:true for full replacement)","operationId":"os_timetables_classes_post","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"classes":{"type":"array","items":{"$ref":"#/components/schemas/TimetableClass"}},"replace":{"type":"boolean","default":false,"description":"If true, replaces all existing entities. If false/omitted, merges with existing (incremental)."},"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}":{"get":{"tags":["Timetables"],"summary":"Retrieve a specific class of a timetable by its ID","description":"`os_timetables_classes-class_get` · minimal role **teacher**\n\nRetrieve a specific class of a timetable by its ID","operationId":"os_timetables_classes-class_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"class":{"$ref":"#/components/schemas/TimetableClass"}}}}}}}},"put":{"tags":["Timetables"],"summary":"Update a specific class of a timetable","description":"`os_timetables_classes-class_put` · minimal role **admin**\n\nUpdate a specific class of a timetable","operationId":"os_timetables_classes-class_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"Name of the class","type":"string"},"level":{"description":"Level of the class","type":"string"},"campus":{"description":"Campus label of the class","type":"string","x-premiumOnly":true},"site":{"description":"Default site of the class. Prefer \"sites\" key","type":"string"},"sites":{"description":"Default sites of the class. As for now, used only with first element","type":"array","items":{"type":"string"}},"classroom":{"description":"Default classroom for the class (format <siteid>:<classroomid>). If several classrooms are set, they are separated by commas","type":"string"},"offgrid":{"description":"On a calendar-type timetable, lessons of this class are scheduled outside the standard timetable grid, using start/end as the source of truth","type":"boolean","x-premiumOnly":true},"time_unit":{"description":"Subdivision count of one hour for off-grid classes (for example 4 exposes 15-minute slots)","type":"integer","minimum":1,"x-premiumOnly":true}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete a specific class of a timetable","description":"`os_timetables_classes-class_delete` · minimal role **admin**\n\nDelete a specific class of a timetable","operationId":"os_timetables_classes-class_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/wishes":{"put":{"tags":["Timetables"],"summary":"Update the preferences of a specific class for the timetable","description":"`os_timetables_classes-wishes_put` · minimal role **admin**\n\nUpdate the preferences of a specific class for the timetable","operationId":"os_timetables_classes-wishes_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"wishes":{"type":"object","description":"Time preferences for this class","properties":{"hours":{"description":"Specific rules on hours for availabilities","type":"array","items":{"description":"Time span with associated rule for availability/wish/preference","type":"object","required":["day","priority"],"oneOf":[{"properties":{"period_begin":{"not":{"anyOf":[{}]}},"period_end":{"not":{"anyOf":[{}]}},"begin":{"not":{"anyOf":[{}]}},"end":{"not":{"anyOf":[{}]}}},"type":"object"},{"anyOf":[{"required":["period_begin"],"type":"object"},{"required":["period_end"],"type":"object"}],"properties":{"begin":{"not":{"anyOf":[{}]}},"end":{"not":{"anyOf":[{}]}}},"type":"object"},{"anyOf":[{"required":["begin"],"type":"object"},{"required":["end"],"type":"object"}],"properties":{"period_begin":{"not":{"anyOf":[{}]}},"period_end":{"not":{"anyOf":[{}]}}},"type":"object"}],"properties":{"day":{"description":"Day, date or cycle day. If no time bound is provided, the wish applies to the whole day.","type":"string","oneOf":[{"format":"date","type":"string"},{"enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"type":"string"},{"pattern":"^[0-9]+$","type":"string"}]},"school_year":{"description":"Optional school year scope for recurring non-dated wishes in calendar mode.","type":"string"},"period_begin":{"description":"Start in period number (exclusive to minute bounds). If omitted while period_end is present, the span starts at the beginning of the day.","type":"integer"},"period_end":{"description":"End in period number (exclusive to minute bounds). This bound is *excluded*, meaning the span is [period_begin, period_end[. If omitted while period_begin is present, the span ends at the end of the day.","type":"integer"},"begin":{"description":"Start in minutes (exclusive to period bounds). If omitted while end is present, the span starts at the beginning of the day.","type":"integer"},"end":{"description":"End in minutes (exclusive to period bounds). If omitted while begin is present, the span ends at the end of the day.","type":"integer"},"priority":{"description":"Priority associated to the rule. \"mandatory\" is *strong* (must ABSOLUTELY be avoided), \"high\" may be strongly avoided if possible, \"medium\" is not preferred, \"preferred\" is positive preference, and \"none\" explicitly erases the effect of previous wishes on the covered span. \"custom\" is a frontend-only intermediate state and is not persisted in Wishes storage.","type":"string","enum":["mandatory","high","medium","preferred","none"]},"sites":{"description":"Optional sites the wishes are referring to","type":"array","items":{"type":"string"}}}}},"time_unit":{"description":"If it is in period number, what is the time unit as in the grid","type":"number","default":1},"time_period":{"description":"If it is in period number, what is the time period as in the grid","type":"number","default":60},"maxhours":{"description":"Maximum number of lesson hours per day (format \"HH:MM\" preferred, integer hours accepted)","oneOf":[{"type":"string","pattern":"^[0-9]{1,3}:[0-5][0-9]$"},{"type":"integer","minimum":0}],"examples":[]},"maxhoursweek":{"description":"Maximum number of lesson hours per week (format \"HH:MM\" preferred, integer hours accepted)","oneOf":[{"type":"string","pattern":"^[0-9]{1,3}:[0-5][0-9]$"},{"type":"integer","minimum":0}],"examples":[]},"comment":{"description":"Free comment, for example to be used by teachers to communicate specific remarks on their wishes","type":"string"},"date_windows":{"description":"Optional array of date window IDs (slugs) to constrain when lessons can be scheduled. Only valid for calendar timetables","type":"array","items":{"type":"string"}}}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete the preferences of a specific class for the timetable","description":"`os_timetables_classes-wishes_delete` · minimal role **admin**\n\nDelete the preferences of a specific class for the timetable","operationId":"os_timetables_classes-wishes_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/subjects":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of subjects associated with a specific class in a timetable","description":"`os_timetables_classes-subjects_get` · minimal role **teacher**\n\nRetrieve the list of subjects associated with a specific class in a timetable","operationId":"os_timetables_classes-subjects_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"with_groups","in":"query","required":false,"schema":{"type":"boolean","description":"Include groups in classes and group sets"},"description":"Include groups in classes and group sets"},{"name":"with_students","in":"query","required":false,"schema":{"type":"boolean","description":"Include students (if studentsonclasses config enabled)"},"description":"Include students (if studentsonclasses config enabled)"},{"name":"with_specialisations","in":"query","required":false,"schema":{"type":"boolean","description":"Include specialisations and validate subjects"},"description":"Include specialisations and validate subjects"},{"name":"with_sites","in":"query","required":false,"schema":{"type":"boolean","description":"Include sites information"},"description":"Include sites information"},{"name":"with_config","in":"query","required":false,"schema":{"type":"boolean","description":"Include timetable configuration"},"description":"Include timetable configuration"},{"name":"with_lessonusage","in":"query","required":false,"schema":{"type":"boolean","description":"Include lesson usage information"},"description":"Include lesson usage information"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"class":{"type":"object","properties":{"id":{"type":"string"},"name":{"description":"Name of the class","type":"string"}}},"classes":{"type":"object","additionalProperties":{"allOf":[{"$ref":"#/components/schemas/TimetableClassBase"},{"properties":{"id":{"type":"string"},"groups":{"allOf":[{"$ref":"#/components/schemas/TimetableClassGroup"},{"description":"Groups (if with_groups=true)"}]}}}]}},"levels":{"type":"array","items":{"type":"string"}},"campuses":{"description":"Configured campus labels","type":"array","x-premiumOnly":true,"items":{"type":"string"}},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"subjecttypemandatory":{"description":"Require a type for each subject assignment","type":"boolean","default":false},"defaulttype":{"type":"string","description":"Default type for subjects (if configured somewhere, such as ExtSync)"},"subjects":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClassSubject"}},"students":{"type":"array","items":{"type":"string"},"description":"Students (if with_students=true and studentsonclasses config enabled)"},"specialisations":{"type":"array","description":"Available specialisations (if with_specialisations=true)","items":{"type":"string"}},"sites":{"type":"object","additionalProperties":{"allOf":[{"$ref":"#/components/schemas/TimetableSite"},{"not":{"properties":{"classrooms":{},"resources":{},"hours.opening":{}}}}]},"description":"Sites information (if with_sites=true)"},"config":{"allOf":[{"$ref":"#/components/schemas/TimetableConfig"},{"not":{"properties":{"colors":{},"description":{},"label":{}}}}],"description":"Timetable configuration (if with_config=true)"},"timeset":{"$ref":"#/components/schemas/TimetableGroupTimeset"},"spaceset":{"$ref":"#/components/schemas/TimetableGroupSpaceset"},"groupset":{"$ref":"#/components/schemas/TimetableGroupGroupset"},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}}}}}}},"post":{"tags":["Timetables"],"summary":"Add a subject to a specific class in a timetable (bulk import is incremental by default, set replace:true for full replacement)","description":"`os_timetables_classes-subjects_post` · minimal role **admin**\n\nAdd a subject to a specific class in a timetable (bulk import is incremental by default, set replace:true for full replacement)","operationId":"os_timetables_classes-subjects_post","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":"object","properties":{"import_class":{"type":"string","description":"Import subjects from another class"},"import_timetable":{"type":"string","description":"Import subjects of a class from a specific timetable ID (requires import_class)"},"with_replacement":{"type":"boolean","description":"When importing, remove current subjects/courses/wishes before copying"},"with_teachers":{"type":"boolean","description":"Import teachers with subjects"},"with_groups":{"type":"boolean","description":"Import groups with subjects (requires import_class)"},"with_incompatibilities":{"type":"boolean","description":"Import subject incompatibilities"},"with_wishes":{"type":"boolean","description":"Import wishes with subjects"},"with_courses":{"type":"boolean","description":"Import courses with subjects"},"with_classrooms":{"type":"boolean","description":"Import classrooms on courses (requires with_courses)"},"with_modality":{"type":"boolean","description":"Import course modality (requires with_courses)"},"with_videolink":{"type":"boolean","description":"Import videoconference links on courses (requires with_courses)"},"with_resources":{"type":"boolean","description":"Import resources on courses (requires with_courses)"},"with_memo":{"type":"boolean","description":"Import comments (memos) on courses (requires with_courses)"},"with_positions":{"type":"boolean","description":"Import course positions when timetable types match (requires with_courses)"},"with_shift":{"type":"boolean","description":"Shift course dates when importing positions (requires with_positions)"},"date_shift":{"type":"string","description":"Date used to realign courses when with_shift is enabled (ISO date)","format":"date"},"subjects":{"type":"array","items":{"$ref":"#/components/schemas/TimetableClassSubject"},"description":"New subjects to add (bulk import, incremental by default)"},"replace":{"type":"boolean","default":false,"description":"If true, replaces all existing entities. If false/omitted, merges with existing (incremental)."},"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/subjects/{subjectid}":{"put":{"tags":["Timetables"],"summary":"Update a specific subject of a class in a timetable","description":"`os_timetables_classes-subjects_put` · minimal role **admin**\n\nUpdate a specific subject of a class in a timetable","operationId":"os_timetables_classes-subjects_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"subjectid","in":"path","required":true,"schema":{"type":"string","description":"subject ID"},"description":"subject ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/TimetableClassSubject"},{"type":"object","properties":{"color":{"type":"string","description":"Subject color"},"syncteachers":{"type":"boolean","description":"Synchronize teachers with existing courses"}}}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"subjectid":{"type":"string","description":"The subject ID"},"subject":{"$ref":"#/components/schemas/TimetableClassSubject"},"color":{"type":"string","description":"Subject color from configuration"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete a specific subject of a class in a timetable","description":"`os_timetables_classes-subjects_delete` · minimal role **admin**\n\nDelete a specific subject of a class in a timetable","operationId":"os_timetables_classes-subjects_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"subjectid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/groups":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of groups associated with a specific class in a timetable (a group is a subset of a class)","description":"`os_timetables_classes-groups_get` · minimal role **teacher**\n\nRetrieve the list of groups associated with a specific class in a timetable (a group is a subset of a class)","operationId":"os_timetables_classes-groups_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"class":{"type":"object","properties":{"id":{"type":"string"},"name":{"description":"Name of the class","type":"string"}},"description":"Requested class"},"classes":{"type":"object","description":"All classes of the timetable, keyed by ID","additionalProperties":{"$ref":"#/components/schemas/TimetableClassBase"}},"groups":{"$ref":"#/components/schemas/TimetableClassGroups"},"levels":{"type":"array","items":{"type":"string"}},"campuses":{"description":"Configured campus labels","type":"array","x-premiumOnly":true,"items":{"type":"string"}},"timeset":{"$ref":"#/components/schemas/TimetableGroupTimeset"},"spaceset":{"$ref":"#/components/schemas/TimetableGroupSpaceset"},"groupset":{"$ref":"#/components/schemas/TimetableGroupGroupset"}}}}}}}},"post":{"tags":["Timetables"],"summary":"Add a group to a specific class in a timetable (bulk import is incremental by default, set replace:true for full replacement)","description":"`os_timetables_classes-groups_post` · minimal role **admin**\n\nAdd a group to a specific class in a timetable (bulk import is incremental by default, set replace:true for full replacement)","operationId":"os_timetables_classes-groups_post","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"import_class":{"type":"string","description":"Class ID to import groups from"},"import_timetable":{"type":"string","description":"Optional timetable ID containing the source class (defaults to current timetable)"},"with_replacement":{"type":"boolean","description":"When importing, wipe current groups of the target class before copying"}},"required":["import_class"]},{"type":"object","properties":{"groups":{"type":"array","description":"Bulk import of class groups (incremental by default)","items":{"allOf":[{"$ref":"#/components/schemas/TimetableClassGroup"},{"type":"object","properties":{"id":{"type":"string","description":"Existing group ID to keep (if provided)"}}}]}},"replace":{"type":"boolean","default":false,"description":"If true, replaces all existing entities. If false/omitted, merges with existing (incremental)."},"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}},"required":["groups"]},{"$ref":"#/components/schemas/TimetableClassGroup"}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"id":{"type":"string","description":"Identifier of the newly created group (single creation mode only)"},"groups":{"$ref":"#/components/schemas/TimetableClassGroups"},"timeset":{"$ref":"#/components/schemas/TimetableGroupTimeset"},"classtimeset":{"type":"array","description":"Partitions newly created during import for this class","items":{"type":"array","items":{"type":"string"}}}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/groups/{groupid}":{"put":{"tags":["Timetables"],"summary":"Update a specific group of a class in a timetable","description":"`os_timetables_classes-groups_put` · minimal role **admin**\n\nUpdate a specific group of a class in a timetable","operationId":"os_timetables_classes-groups_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"groupid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/TimetableClassGroup"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"groups":{"$ref":"#/components/schemas/TimetableClassGroups"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete a specific group of a class in a timetable","description":"`os_timetables_classes-groups_delete` · minimal role **admin**\n\nDelete a specific group of a class in a timetable","operationId":"os_timetables_classes-groups_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"groupid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/groups/{groupid}/wishes":{"put":{"tags":["Timetables"],"summary":"Update wishes of a specific group of a class in a timetable","description":"`os_timetables_classes-groups-wishes_put` · minimal role **admin**\n\nUpdate wishes of a specific group of a class in a timetable","operationId":"os_timetables_classes-groups-wishes_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"groupid","in":"path","required":true,"schema":{"type":"string","description":"group ID"},"description":"group ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"wishes":{"$ref":"#/components/schemas/Wishes"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete wishes of a specific group of a class in a timetable","description":"`os_timetables_classes-groups-wishes_delete` · minimal role **admin**\n\nDelete wishes of a specific group of a class in a timetable","operationId":"os_timetables_classes-groups-wishes_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"groupid","in":"path","required":true,"schema":{"type":"string","description":"group ID"},"description":"group ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/students":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of students associated with a specific class in a timetable (warning: related to a specific setting of the account)","description":"`os_timetables_classes-students_get` · minimal role **teacher**\n\nRetrieve the list of students associated with a specific class in a timetable (warning: related to a specific setting of the account)","operationId":"os_timetables_classes-students_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"class":{"type":"object","properties":{"id":{"type":"string"},"name":{"description":"Name of the class","type":"string"}}},"students":{"type":"object","description":"Students assigned to the class, keyed by student ID","additionalProperties":{"$ref":"#/components/schemas/UserMinimal"}}}}}}}}},"put":{"tags":["Timetables"],"summary":"Update the list of students for a specific class in a timetable (warning: related to a specific setting of the account)","description":"`os_timetables_classes-students_put` · minimal role **admin**\n\nUpdate the list of students for a specific class in a timetable (warning: related to a specific setting of the account)","operationId":"os_timetables_classes-students_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"id":{"type":"string","description":"Student ID to assign to the class"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/students/{studentid}":{"delete":{"tags":["Timetables"],"summary":"Delete a specific student from a class in a timetable (warning: related to a specific setting of the account)","description":"`os_timetables_classes-students_delete` · minimal role **admin**\n\nDelete a specific student from a class in a timetable (warning: related to a specific setting of the account)","operationId":"os_timetables_classes-students_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"},{"name":"studentid","in":"path","required":true,"schema":{"type":"string","description":"student ID"},"description":"student ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/courses":{"put":{"tags":["Timetables"],"summary":"Update the courses (= lessons) of a specific class in a timetable","description":"`os_timetables_classes-courses_put` · minimal role **admin**\n\nUpdate the courses (= lessons) of a specific class in a timetable","operationId":"os_timetables_classes-courses_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"courses":{"description":"Array of lessons replacing the current class courses","type":"array","items":{"$ref":"#/components/schemas/LessonClass"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/classes/{classid}/incompatibilities":{"put":{"tags":["Timetables"],"summary":"Update the incompatibilities between subjects of a specific class in a timetable","description":"`os_timetables_classes-incompatibilities_put` · minimal role **admin**\n\nUpdate the incompatibilities between subjects of a specific class in a timetable","operationId":"os_timetables_classes-incompatibilities_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"incompatibilities":{"type":"array","description":"List of incompatibility rules applied to class subjects","items":{"type":"object","properties":{"subject_before":{"type":"string","description":"Subject ID that should not be followed by another one"},"subject_after":{"type":"string","description":"Subject ID to protect from being adjacent"},"type":{"description":"Type of the rule, as the time span to consider its effects","type":"string","enum":["consecutive","halfday","day","week","always"]}},"required":["subject_before","subject_after","type"]}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"subjects":{"type":"object","description":"Subjects of the class with updated incompatibilities","additionalProperties":{"$ref":"#/components/schemas/TimetableClassSubject"}}}}}}}}}},"/api/timetables/{timetableid}/groups":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of group alignements (groups of different classes attending lessons together), group partitions/class divisions (class strictly divided into given groups) and groups of groups (a set of groups of same or different classes, attending the same lessons together), associated with a specific timetable","description":"`os_timetables_groups_get` · minimal role **teacher**\n\nRetrieve the list of group alignements (groups of different classes attending lessons together), group partitions/class divisions (class strictly divided into given groups) and groups of groups (a set of groups of same or different classes, attending the same lessons together), associated with a specific timetable","operationId":"os_timetables_groups_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"classes":{"type":"object","description":"Classes of the timetable with their groups","additionalProperties":{"allOf":[{"$ref":"#/components/schemas/TimetableClassBase"},{"type":"object","properties":{"groups":{"$ref":"#/components/schemas/TimetableClassGroups"}}}]}},"timeset":{"$ref":"#/components/schemas/TimetableGroupTimeset"},"spaceset":{"$ref":"#/components/schemas/TimetableGroupSpaceset"},"groupset":{"$ref":"#/components/schemas/TimetableGroupGroupset"},"levels":{"type":"array","items":{"type":"string"}},"campuses":{"description":"Configured campus labels","type":"array","x-premiumOnly":true,"items":{"type":"string"}},"type":{"description":"Type of timetable. \"Week\": weekly schedule repeated over time. \"cycle\": multi-day cycle (e.g. 6-day rotating schedule), \"calendar\": individual dates are scheduled explicitly, with no repeating pattern","type":"string","enum":["week","cycle","calendar"],"default":"week"}}}}}}}},"post":{"tags":["Timetables"],"summary":"Create a new group alignement and/or partition and/or group of groups","description":"`os_timetables_groups_post` · minimal role **admin**\n\nCreate a new group alignement and/or partition and/or group of groups","operationId":"os_timetables_groups_post","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"timeset":{"type":"array","description":"List of group IDs forming the partition to add","items":{"type":"string"}},"replace":{"type":"array","description":"Existing partition to replace (list of group IDs)","items":{"type":"string"}}},"required":["timeset"]},{"type":"object","properties":{"spaceset":{"type":"array","description":"List of group IDs forming the alignment to add","items":{"type":"string"}},"replace":{"type":"array","description":"Existing alignment to replace (list of group IDs)","items":{"type":"string"}}},"required":["spaceset"]},{"type":"object","properties":{"groupset":{"$ref":"#/components/schemas/TimetableGroupGroupsetItem"}},"required":["groupset"]}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"id":{"type":"string","description":"Identifier of the newly created group of groups (when groupset is provided)"},"timeset":{"$ref":"#/components/schemas/TimetableGroupTimeset"},"spaceset":{"$ref":"#/components/schemas/TimetableGroupSpaceset"},"groupset":{"$ref":"#/components/schemas/TimetableGroupGroupset"}}}}}}}},"delete":{"tags":["Timetables"],"summary":"Delete a specific group alignement or group partition/class division or group of groups of a timetable","description":"`os_timetables_groups_delete` · minimal role **admin**\n\nDelete a specific group alignement or group partition/class division or group of groups of a timetable","operationId":"os_timetables_groups_delete","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"anyOf":[{"type":"object","properties":{"timeset":{"type":"array","description":"Partition to delete (list of group IDs)","items":{"type":"string"}}},"required":["timeset"]},{"type":"object","properties":{"spaceset":{"type":"array","description":"Alignment to delete (list of group IDs)","items":{"type":"string"}}},"required":["spaceset"]},{"type":"object","properties":{"groupset":{"type":"string","description":"Identifier of the group of groups to delete"}},"required":["groupset"]}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"timeset":{"$ref":"#/components/schemas/TimetableGroupTimeset"},"spaceset":{"$ref":"#/components/schemas/TimetableGroupSpaceset"},"groupset":{"$ref":"#/components/schemas/TimetableGroupGroupset"}}}}}}}}},"/api/timetables/{timetableid}/groups/{groupid}":{"put":{"tags":["Timetables"],"summary":"Update a specific group of groups of a timetable","description":"`os_timetables_groups_put` · minimal role **admin**\n\nUpdate a specific group of groups of a timetable","operationId":"os_timetables_groups_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"groupid","in":"path","required":true,"schema":{"type":"string","description":"Group of groups ID"},"description":"Group of groups ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"groupset":{"$ref":"#/components/schemas/TimetableGroupGroupsetItem"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"id":{"type":"string","description":"Group of groups ID"},"groupset":{"$ref":"#/components/schemas/TimetableGroupGroupset"}}}}}}}}},"/api/timetables/{timetableid}/students":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of students associated with a specific timetable (warning: related to a specific setting of the account)","description":"`os_timetables_students_get` · minimal role **teacher**\n\nRetrieve the list of students associated with a specific timetable (warning: related to a specific setting of the account)","operationId":"os_timetables_students_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"filter","in":"query","required":false,"schema":{"type":"string","enum":["available"],"description":"When set to \"available\", only students not yet assigned to any class are returned"},"description":"When set to \"available\", only students not yet assigned to any class are returned"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"students":{"type":"object","description":"Students keyed by user ID","additionalProperties":{"$ref":"#/components/schemas/UserMinimal"}}}}}}}}}},"/api/timetables/{timetableid}/subjects":{"get":{"tags":["Timetables"],"summary":"Retrieve the list of all subjects associated with a specific timetable","description":"`os_timetables_subjects_get` · minimal role **teacher**\n\nRetrieve the list of all subjects associated with a specific timetable","operationId":"os_timetables_subjects_get","x-module":"timetables","x-access":"teacher","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"classes":{"type":"object","description":"Mapping between class IDs and their display name","additionalProperties":{"type":"string"}},"subjects":{"type":"object","description":"Subjects grouped by class ID","additionalProperties":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClassSubject"}}},"schoolyears":{"type":"array","items":{"$ref":"#/components/schemas/SchoolYear"}}}}}}}}}},"/api/timetables/{timetableid}/courses":{"put":{"tags":["Timetables"],"summary":"Update the courses (= lessons) of a specific timetable","description":"`os_timetables_courses_put` · minimal role **admin**\n\nUpdate the courses (= lessons) of a specific timetable","operationId":"os_timetables_courses_put","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"courses":{"type":"object","description":"Courses to replace for each class","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/LessonClass"}}},"lessons":{"type":"array","description":"Global lessons (for transversal groups or calendars)","items":{"$ref":"#/components/schemas/LessonClass"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"patch":{"tags":["Timetables"],"summary":"Patch courses of a specific timetable (added/updated/removed)","description":"`os_timetables_courses_patch` · minimal role **admin**\n\nPatch courses of a specific timetable (added/updated/removed)","operationId":"os_timetables_courses_patch","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"added":{"type":"array","description":"Courses to create","items":{"$ref":"#/components/schemas/LessonClass"}},"updated":{"type":"array","description":"Courses to update (must include _id and _osrev)","items":{"$ref":"#/components/schemas/LessonClass"}},"removed":{"type":"array","description":"List of course identifiers to delete","items":{"oneOf":[{"type":"string","description":"course _id"},{"type":"object","properties":{"_id":{"type":"string"}},"required":["_id"]}]}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/timetables/{timetableid}/courses/{id}":{"patch":{"tags":["Timetables"],"summary":"Partially update one course or lesson by its stable ID. If _osrev is omitted, the patch is forced on the latest backend version. If _osrev is provided and mismatches, the request fails.","description":"`os_timetables_courses-course_patch` · minimal role **admin**\n\nPartially update one course or lesson by its stable ID. If _osrev is omitted, the patch is forced on the latest backend version. If _osrev is provided and mismatches, the request fails.","operationId":"os_timetables_courses-course_patch","x-module":"timetables","x-access":"admin","parameters":[{"name":"timetableid","in":"path","required":true,"schema":{"type":"string","description":"timetable ID"},"description":"timetable ID"},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"course or lesson stable ID (_id)"},"description":"course or lesson stable ID (_id)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allOf":[{"$ref":"#/components/schemas/Lesson"},{"type":"object","properties":{"assoc":{"description":"Associated lessons have groups switching together","type":"array","items":{"$ref":"#/components/schemas/LessonBase"}},"concat":{"description":"Concatenated lessons are strictly happening one after the other, they cannot be cut","type":"array","items":{"$ref":"#/components/schemas/LessonBase"}}}}],"description":"Partial course object. Only provided fields are modified; null removes a field. _osrev is optional: omit it to force the patch, provide it to enforce optimistic locking.","properties":{"_osrev":{"type":"string","description":"Optional optimistic-lock revision. If provided and stale, the patch fails."},"class":{"type":"string","description":"Optional target class ID when relocating a class course. Omit to keep the current location."}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/country":{"get":{"tags":["Admin"],"summary":"Retrieve the country of the account","description":"`os_admin_country_get` · minimal role **teacher**\n\nRetrieve the country of the account","operationId":"os_admin_country_get","x-module":"admin","x-access":"teacher","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"country":{"description":"Account country","type":"string"}}}}}}}}},"/api/admin/users":{"get":{"tags":["Admin"],"summary":"List the account's user accounts, with their roles and state. Use this to list, count, or look up users and their access rights.","description":"`os_admin_users_get` · minimal role **teacher**\n\nList the account's user accounts, with their roles and state. Use this to list, count, or look up users and their access rights.","operationId":"os_admin_users_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"state","in":"query","required":false,"schema":{"type":"string","enum":["active","former"],"description":"Filter by active or former users. Defaults to \"active\""},"description":"Filter by active or former users. Defaults to \"active\""}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"users":{"description":"Users (with roles: admin, teacher, student...)","type":"object","additionalProperties":{"$ref":"#/components/schemas/User"}},"countusers":{"type":"object","description":"Number of users per role","additionalProperties":{"type":"integer"}},"middlename":{"description":"Activate middle name support","type":"boolean","default":false},"namecapitalize":{"description":"Name parts to capitalize (first name, middle name, last name)","type":"array","uniqueItems":true,"default":[],"items":{"type":"string","enum":["first","middle","last"]}},"login":{"description":"Pattern to generate user's login","type":"string","enum":["firstlast","lastfirst","idnumber"],"default":"firstlast","readOnly":true},"customroles":{"type":"object","x-premiumOnly":true,"properties":{"^[a-z0-9-]+$":{"description":"Custom roles for admin, restricting their access to the platform (requires custom roles option)","type":"object","properties":{"name":{"type":"string"},"exclude_modules":{"type":"array","items":{"type":"string"}},"exclude_endpoints":{"type":"array","items":{"type":"string"}}}}}},"useremail":{"description":"Email address of the currently logged-in user","type":"string","format":"email"}}}}}}}},"post":{"tags":["Admin"],"summary":"Create or update users (students, teachers or generic staff)","description":"`os_admin_users_post` · minimal role **admin**\n\nCreate or update users (students, teachers or generic staff)","operationId":"os_admin_users_post","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"students":{"type":"array","description":"Students to import in bulk. Provide `id` to update an existing user, omit it to create a new student.","items":{"allOf":[{"$ref":"#/components/schemas/UserMinimal"},{"type":"object","properties":{"id":{"type":"string","description":"Existing student ID to update"}}}]}},"replace":{"type":"boolean","default":false,"description":"If true, replaces all existing entities. If false/omitted, merges with existing (incremental)."},"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}},"required":["students"]},{"type":"object","properties":{"teachers":{"type":"array","description":"Teachers to import in bulk. Provide `id` to update an existing user, omit it to create a new teacher.","items":{"allOf":[{"$ref":"#/components/schemas/UserMinimal"},{"type":"object","properties":{"id":{"type":"string","description":"Existing teacher ID to update"},"servicehours":{"description":"Service hours, i.e. the number of hours the teacher should teach","type":"integer"},"subjects":{"description":"Subjects to be taught by the teacher (useful for automatic suggestions)","type":"object","additionalProperties":{"type":"object","required":["name","code"],"properties":{"name":{"description":"Subject name","type":"string"},"code":{"description":"Subject code","type":"string"}}}},"external":{"description":"External teacher flag (only stored if true)","type":"boolean","x-premiumOnly":true}}}]}},"replace":{"type":"boolean","default":false,"description":"If true, replaces all existing entities. If false/omitted, merges with existing (incremental)."},"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}},"required":["teachers"]},{"type":"object","properties":{"staff":{"type":"array","description":"Staff members to import in bulk. Provide `id` to update an existing user, omit it to create a new staff member.","items":{"allOf":[{"$ref":"#/components/schemas/UserMinimal"},{"type":"object","properties":{"id":{"type":"string","description":"Existing staff ID to update"},"servicehours":{"description":"Service hours, i.e. the number of hours the teacher should teach","type":"integer"}}}]}},"replace":{"type":"boolean","default":false,"description":"If true, replaces all existing entities. If false/omitted, merges with existing (incremental)."},"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}},"required":["staff"]},{"$ref":"#/components/schemas/User"}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Admin"],"summary":"Activate or deactivate or change passwords on multiple users","description":"`os_admin_users_put` · minimal role **admin**\n\nActivate or deactivate or change passwords on multiple users","operationId":"os_admin_users_put","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"object","description":"Users keyed by ID with the fields to update","additionalProperties":{"type":"object","properties":{"password":{"description":"Password (hashed + salt + peppper)","type":"string"},"active":{"type":"boolean","description":"False to deactivate the user, true/omitted keeps them active"}}}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"patch":{"tags":["Admin"],"summary":"Partial update of multiple users (merge only provided fields, null removes field)","description":"`os_admin_users_patch` · minimal role **admin**\n\nPartial update of multiple users (merge only provided fields, null removes field)","operationId":"os_admin_users_patch","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"object","description":"Users keyed by ID with the fields to merge (null = remove field)","additionalProperties":{"description":"Partial editable user object. Only provided fields are modified; null removes a field. auth.breakGlass can be updated here; credentials and auth provider links are handled by dedicated endpoints.","type":"object","allOf":[{"$ref":"#/components/schemas/UserMinimal"},{"$ref":"#/components/schemas/Placements"},{"type":"object","properties":{"roles":{"description":"List of roles","type":"array","items":{"type":"string","enum":["superadmin","admin","staf","teacher","student"]}},"customrole":{"description":"Custom role","type":"string"},"servicehours":{"description":"Service hours, i.e. the number of hours the teacher should teach","type":"integer"},"external":{"description":"External teacher flag (only stored if true)","type":"boolean","x-premiumOnly":true},"subjects":{"description":"Subjects to be taught by the teacher (useful for automatic suggestions)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"description":"Subject name","type":"string"},"code":{"description":"Subject code","type":"string"}},"required":["name","code"]}},"wishes":{"allOf":[{"$ref":"#/components/schemas/WishesTeachers"},{"description":"Teacher's wishes/availabilities"}]},"auth":{"$ref":"#/components/schemas/AuthEditable"},"schedules_options":{"$ref":"#/components/schemas/SchedulesOptions"},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}}]}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete multiple users","description":"`os_admin_users_delete` · minimal role **admin**\n\nDelete multiple users","operationId":"os_admin_users_delete","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"users":{"type":"array","description":"IDs of users to delete","items":{"type":"string"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/users/{userid}":{"get":{"tags":["Admin"],"summary":"Retrieve the information of a specific user","description":"`os_admin_user_get` · minimal role **teacher**\n\nRetrieve the information of a specific user","operationId":"os_admin_user_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"user":{"$ref":"#/components/schemas/User"}}}}}}}},"put":{"tags":["Admin"],"summary":"Update the information of a specific user","description":"`os_admin_user_put` · minimal role **admin**\n\nUpdate the information of a specific user","operationId":"os_admin_user_put","x-module":"admin","x-access":"admin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/UserEditable"}],"description":"Editable user fields plus auth.breakGlass. Omitted fields are cleared by PUT. Credentials and auth provider links are handled by dedicated endpoints."}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"patch":{"tags":["Admin"],"summary":"Partial update of a specific user (merge only provided fields, null removes field)","description":"`os_admin_user_patch` · minimal role **admin**\n\nPartial update of a specific user (merge only provided fields, null removes field)","operationId":"os_admin_user_patch","x-module":"admin","x-access":"admin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"description":"Partial editable user object. Only provided fields are modified; null removes a field. auth.breakGlass can be updated here; credentials and auth provider links are handled by dedicated endpoints.","type":"object","allOf":[{"$ref":"#/components/schemas/UserMinimal"},{"$ref":"#/components/schemas/Placements"},{"type":"object","properties":{"roles":{"description":"List of roles","type":"array","items":{"type":"string","enum":["superadmin","admin","staf","teacher","student"]}},"customrole":{"description":"Custom role","type":"string"},"servicehours":{"description":"Service hours, i.e. the number of hours the teacher should teach","type":"integer"},"external":{"description":"External teacher flag (only stored if true)","type":"boolean","x-premiumOnly":true},"subjects":{"description":"Subjects to be taught by the teacher (useful for automatic suggestions)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"description":"Subject name","type":"string"},"code":{"description":"Subject code","type":"string"}},"required":["name","code"]}},"wishes":{"allOf":[{"$ref":"#/components/schemas/WishesTeachers"},{"description":"Teacher's wishes/availabilities"}]},"auth":{"$ref":"#/components/schemas/AuthEditable"},"schedules_options":{"$ref":"#/components/schemas/SchedulesOptions"},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}}]}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a specific user","description":"`os_admin_user_delete` · minimal role **admin**\n\nDelete a specific user","operationId":"os_admin_user_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/users/{userid}/impersonate":{"post":{"tags":["Admin"],"summary":"Impersonate a user (superadmin only)","description":"`os_admin_user_impersonate_post` · minimal role **superadmin**\n\nImpersonate a user (superadmin only)","operationId":"os_admin_user_impersonate_post","x-module":"admin","x-access":"superadmin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/admins":{"get":{"tags":["Admin"],"summary":"List the account's administrators. Use this to list or count admin users.","description":"`os_admin_admins_get` · minimal role **teacher**\n\nList the account's administrators. Use this to list or count admin users.","operationId":"os_admin_admins_get","x-module":"admin","x-access":"teacher","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"admins":{"$ref":"#/components/schemas/User"},"countusers":{"type":"object","description":"Number of admins per role","additionalProperties":{"type":"integer"}},"middlename":{"description":"Activate middle name support","type":"boolean","default":false},"namecapitalize":{"description":"Name parts to capitalize (first name, middle name, last name)","type":"array","uniqueItems":true,"default":[],"items":{"type":"string","enum":["first","middle","last"]}},"login":{"description":"Pattern to generate user's login","type":"string","enum":["firstlast","lastfirst","idnumber"],"default":"firstlast","readOnly":true},"customroles":{"type":"object","x-premiumOnly":true,"properties":{"^[a-z0-9-]+$":{"description":"Custom roles for admin, restricting their access to the platform (requires custom roles option)","type":"object","properties":{"name":{"type":"string"},"exclude_modules":{"type":"array","items":{"type":"string"}},"exclude_endpoints":{"type":"array","items":{"type":"string"}}}}}},"useremail":{"description":"Email address of the currently logged-in user","type":"string","format":"email"}}}}}}}}},"/api/admin/staff":{"get":{"tags":["Admin"],"summary":"Retrieve the list of staff members","description":"`os_admin_staffmembers_get` · minimal role **staff**\n\nRetrieve the list of staff members","operationId":"os_admin_staffmembers_get","x-module":"admin","x-access":"staff","parameters":[{"name":"state","in":"query","required":false,"schema":{"type":"string","enum":["active","former"],"description":"Filter by current or former staff. Defaults to \"active\""},"description":"Filter by current or former staff. Defaults to \"active\""}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"staff":{"$ref":"#/components/schemas/User"},"countusers":{"type":"object","description":"Number of staff members per role","additionalProperties":{"type":"integer"}},"middlename":{"description":"Activate middle name support","type":"boolean","default":false},"namecapitalize":{"description":"Name parts to capitalize (first name, middle name, last name)","type":"array","uniqueItems":true,"default":[],"items":{"type":"string","enum":["first","middle","last"]}},"login":{"description":"Pattern to generate user's login","type":"string","enum":["firstlast","lastfirst","idnumber"],"default":"firstlast","readOnly":true},"customroles":{"type":"object","x-premiumOnly":true,"properties":{"^[a-z0-9-]+$":{"description":"Custom roles for admin, restricting their access to the platform (requires custom roles option)","type":"object","properties":{"name":{"type":"string"},"exclude_modules":{"type":"array","items":{"type":"string"}},"exclude_endpoints":{"type":"array","items":{"type":"string"}}}}}},"useremail":{"description":"Email address of the currently logged-in user","type":"string","format":"email"}}}}}}}},"post":{"tags":["Admin"],"summary":"Create a staff member in the directory (a user with the staff role).","description":"`os_admin_staff_post` · minimal role **admin**\n\nCreate a staff member in the directory (a user with the staff role).","operationId":"os_admin_staff_post","x-module":"admin","x-access":"admin","parameters":[{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMinimal"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/staff/{staffid}":{"get":{"tags":["Admin"],"summary":"Retrieve the information of a specific staff member","description":"`os_admin_staff_get` · minimal role **staff**\n\nRetrieve the information of a specific staff member","operationId":"os_admin_staff_get","x-module":"admin","x-access":"staff","parameters":[{"name":"staffid","in":"path","required":true,"schema":{"type":"string","description":"staff ID"},"description":"staff ID"},{"name":"with_schoolyears","in":"query","required":false,"schema":{"type":"boolean","description":"Include school years metadata in the response"},"description":"Include school years metadata in the response"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"staff":{"$ref":"#/components/schemas/User"},"current_school_year":{"type":"string","description":"Current school year ID (if requested)"},"school_years":{"type":"object","description":"School years metadata (if requested)","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}}}}}}}}},"patch":{"tags":["Admin"],"summary":"Update a staff member by id (merge only provided fields, null removes a field; the user must already have the staff role).","description":"`os_admin_staff_patch` · minimal role **admin**\n\nUpdate a staff member by id (merge only provided fields, null removes a field; the user must already have the staff role).","operationId":"os_admin_staff_patch","x-module":"admin","x-access":"admin","parameters":[{"name":"staffid","in":"path","required":true,"schema":{"type":"string","description":"User id of the staff member to update."},"description":"User id of the staff member to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMinimal"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a staff member by id (the user must have the staff role).","description":"`os_admin_staff_delete` · minimal role **admin**\n\nDelete a staff member by id (the user must have the staff role).","operationId":"os_admin_staff_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"staffid","in":"path","required":true,"schema":{"type":"string","description":"User id of the staff member to delete."},"description":"User id of the staff member to delete."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/teachers":{"get":{"tags":["Admin"],"summary":"List the account's teachers (the full teacher directory). Use this to list, count, or look up teachers.","description":"`os_admin_teachers_get` · minimal role **teacher**\n\nList the account's teachers (the full teacher directory). Use this to list, count, or look up teachers.","operationId":"os_admin_teachers_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"state","in":"query","required":false,"schema":{"type":"string","enum":["active","former"],"description":"Filter teachers by state. Defaults to \"active\""},"description":"Filter teachers by state. Defaults to \"active\""}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"teachers":{"type":"object","description":"Teachers keyed by user ID","additionalProperties":{"$ref":"#/components/schemas/User"}},"countusers":{"type":"object","description":"Number of teachers per role","additionalProperties":{"type":"integer"}},"middlename":{"description":"Activate middle name support","type":"boolean","default":false},"namecapitalize":{"description":"Name parts to capitalize (first name, middle name, last name)","type":"array","uniqueItems":true,"default":[],"items":{"type":"string","enum":["first","middle","last"]}},"login":{"description":"Pattern to generate user's login","type":"string","enum":["firstlast","lastfirst","idnumber"],"default":"firstlast","readOnly":true},"customroles":{"type":"object","x-premiumOnly":true,"properties":{"^[a-z0-9-]+$":{"description":"Custom roles for admin, restricting their access to the platform (requires custom roles option)","type":"object","properties":{"name":{"type":"string"},"exclude_modules":{"type":"array","items":{"type":"string"}},"exclude_endpoints":{"type":"array","items":{"type":"string"}}}}}},"useremail":{"description":"Email address of the currently logged-in user","type":"string","format":"email"}}}}}}}},"post":{"tags":["Admin"],"summary":"Create a teacher in the directory (a user with the teacher role).","description":"`os_admin_teachers_post` · minimal role **admin**\n\nCreate a teacher in the directory (a user with the teacher role).","operationId":"os_admin_teachers_post","x-module":"admin","x-access":"admin","parameters":[{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMinimal"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/teachers/{teacherid}":{"get":{"tags":["Admin"],"summary":"Retrieve the information of a specific teacher","description":"`os_admin_teacher_get` · minimal role **teacher**\n\nRetrieve the information of a specific teacher","operationId":"os_admin_teacher_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"},{"name":"with_schoolyears","in":"query","required":false,"schema":{"type":"boolean","description":"Include school years information (current and list)"},"description":"Include school years information (current and list)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"teacher":{"$ref":"#/components/schemas/User"},"opening_hours":{"description":"Global school opening hours by day","type":"object","patternProperties":{"^(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$":{"type":"object","required":["from","to"],"properties":{"from":{"type":"string","pattern":"^([0-1][0-9]|2[0-3]):[0-5][0-9]$"},"to":{"type":"string","pattern":"^([0-1][0-9]|2[0-3]):[0-5][0-9]$"}}}}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"school_years":{"description":"School years (academic years)","type":"array","items":{"type":"object","required":["name","date_start","date_end"],"properties":{"name":{"description":"Name of the school year","type":"string"},"date_start":{"description":"Start date","type":"string","format":"date"},"date_end":{"description":"End date","type":"string","format":"date"},"holidays":{"description":"Holidays","type":"array","items":{"type":"object","required":["name","begin","end"],"properties":{"name":{"type":"string"},"begin":{"type":"string","format":"date"},"end":{"type":"string","format":"date"}}}},"altweeks":{"description":"Array of alternate weeks to determine wether to change the alterations at some point, mainly because of holidays","type":"array","items":{"type":"integer"}}}}},"absences":{"type":"object","description":"Absence records for the teacher (current school year), keyed by absence ID","additionalProperties":{"$ref":"#/components/schemas/AbsenceTeacher"}},"subjects":{"type":"object","description":"Subjects referenced in absences/substitutes, keyed by subject ID"},"classes":{"type":"object","description":"Classes referenced in absences/substitutes, keyed by class ID"},"substitute_teachers":{"type":"object","description":"Substitute teachers referenced in absences, keyed by user ID","additionalProperties":{"$ref":"#/components/schemas/UserMinimal"}}}}}}}}},"patch":{"tags":["Admin"],"summary":"Update a teacher by id (merge only provided fields, null removes a field; the user must already have the teacher role).","description":"`os_admin_teachers_patch` · minimal role **admin**\n\nUpdate a teacher by id (merge only provided fields, null removes a field; the user must already have the teacher role).","operationId":"os_admin_teachers_patch","x-module":"admin","x-access":"admin","parameters":[{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"User id of the teacher to update."},"description":"User id of the teacher to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMinimal"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a teacher by id (the user must have the teacher role).","description":"`os_admin_teachers_delete` · minimal role **admin**\n\nDelete a teacher by id (the user must have the teacher role).","operationId":"os_admin_teachers_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"User id of the teacher to delete."},"description":"User id of the teacher to delete."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/students":{"get":{"tags":["Admin"],"summary":"List the account's students (the full student directory). Use this to list, count, or look up students.","description":"`os_admin_students_get` · minimal role **teacher**\n\nList the account's students (the full student directory). Use this to list, count, or look up students.","operationId":"os_admin_students_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"state","in":"query","required":false,"schema":{"type":"string","enum":["active","former"],"description":"Filter by current or former students. Defaults to \"active\""},"description":"Filter by current or former students. Defaults to \"active\""}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"students":{"type":"object","description":"Students keyed by ID","additionalProperties":{"$ref":"#/components/schemas/User"}},"countusers":{"type":"object","description":"Number of students per role","additionalProperties":{"type":"integer"}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"school_years":{"description":"School years (academic years)","type":"array","items":{"type":"object","required":["name","date_start","date_end"],"properties":{"name":{"description":"Name of the school year","type":"string"},"date_start":{"description":"Start date","type":"string","format":"date"},"date_end":{"description":"End date","type":"string","format":"date"},"holidays":{"description":"Holidays","type":"array","items":{"type":"object","required":["name","begin","end"],"properties":{"name":{"type":"string"},"begin":{"type":"string","format":"date"},"end":{"type":"string","format":"date"}}}},"altweeks":{"description":"Array of alternate weeks to determine wether to change the alterations at some point, mainly because of holidays","type":"array","items":{"type":"integer"}}}}},"middlename":{"description":"Activate middle name support","type":"boolean","default":false},"namecapitalize":{"description":"Name parts to capitalize (first name, middle name, last name)","type":"array","uniqueItems":true,"default":[],"items":{"type":"string","enum":["first","middle","last"]}},"login":{"description":"Pattern to generate user's login","type":"string","enum":["firstlast","lastfirst","idnumber"],"default":"firstlast","readOnly":true},"customroles":{"type":"object","x-premiumOnly":true,"properties":{"^[a-z0-9-]+$":{"description":"Custom roles for admin, restricting their access to the platform (requires custom roles option)","type":"object","properties":{"name":{"type":"string"},"exclude_modules":{"type":"array","items":{"type":"string"}},"exclude_endpoints":{"type":"array","items":{"type":"string"}}}}}},"useremail":{"description":"Email address of the currently logged-in user","type":"string","format":"email"}}}}}}}},"post":{"tags":["Admin"],"summary":"Create a student in the directory (a user with the student role).","description":"`os_admin_students_post` · minimal role **admin**\n\nCreate a student in the directory (a user with the student role).","operationId":"os_admin_students_post","x-module":"admin","x-access":"admin","parameters":[{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMinimal"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Admin"],"summary":"Update multiple students (class/group placements)","description":"`os_admin_students_put` · minimal role **admin**\n\nUpdate multiple students (class/group placements)","operationId":"os_admin_students_put","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"students":{"type":"array","description":"Student IDs to update","items":{"type":"string"}},"schoolyear":{"type":"string","description":"Target school year ID"},"placement":{"description":"Class placement to apply (mutually exclusive with `placements`)","$ref":"#/components/schemas/Placement"},"placements":{"type":"array","description":"Detailed class/group placements to merge (mutually exclusive with `placement`)","items":{"$ref":"#/components/schemas/Placement"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/students/{studentid}":{"patch":{"tags":["Admin"],"summary":"Update a student by id (merge only provided fields, null removes a field; the user must already have the student role).","description":"`os_admin_students_patch` · minimal role **admin**\n\nUpdate a student by id (merge only provided fields, null removes a field; the user must already have the student role).","operationId":"os_admin_students_patch","x-module":"admin","x-access":"admin","parameters":[{"name":"studentid","in":"path","required":true,"schema":{"type":"string","description":"User id of the student to update."},"description":"User id of the student to update."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/UserMinimal"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a student by id (the user must have the student role).","description":"`os_admin_students_delete` · minimal role **admin**\n\nDelete a student by id (the user must have the student role).","operationId":"os_admin_students_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"studentid","in":"path","required":true,"schema":{"type":"string","description":"User id of the student to delete."},"description":"User id of the student to delete."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"get":{"tags":["Admin"],"summary":"Retrieve the information of a specific student","description":"`os_admin_student_get` · minimal role **teacher**\n\nRetrieve the information of a specific student","operationId":"os_admin_student_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"studentid","in":"path","required":true,"schema":{"type":"string","description":"student ID"},"description":"student ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"student":{"$ref":"#/components/schemas/User"},"absences":{"type":"object","description":"Absence records for the student, keyed by absence ID","additionalProperties":{"$ref":"#/components/schemas/AbsenceStudent"}}}}}}}}}},"/api/admin/users/{userid}/password":{"get":{"tags":["Admin"],"summary":"Retrieve the password information of a specific user (undefined OR login.password.defined OR login.password.firsttime)","description":"`os_admin_user_password_get` · minimal role **admin**\n\nRetrieve the password information of a specific user (undefined OR login.password.defined OR login.password.firsttime)","operationId":"os_admin_user_password_get","x-module":"admin","x-access":"admin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"status":{"type":"string","description":"Current password state for the user","enum":["undefined","login.password.defined","login.password.firsttime"]},"login":{"description":"Login","type":"string"}}}}}}}},"put":{"tags":["Admin"],"summary":"Update the password of a specific user (to be changed on first login)","description":"`os_admin_user_password_put` · minimal role **admin**\n\nUpdate the password of a specific user (to be changed on first login)","operationId":"os_admin_user_password_put","x-module":"admin","x-access":"admin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"password":{"description":"Password (hashed + salt + peppper)","type":"string"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"login":{"description":"Login","type":"string"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete the password of a specific user","description":"`os_admin_user_password_delete` · minimal role **admin**\n\nDelete the password of a specific user","operationId":"os_admin_user_password_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/users/{userid}/auth":{"get":{"tags":["Admin"],"summary":"Retrieve authentication metadata for a specific user. OIDC provider links remain managed by the OIDC flow and can be unlinked from here.","description":"`os_admin_user_auth_get` · minimal role **admin**\n\nRetrieve authentication metadata for a specific user. OIDC provider links remain managed by the OIDC flow and can be unlinked from here.","operationId":"os_admin_user_auth_get","x-module":"admin","x-access":"admin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"auth":{"$ref":"#/components/schemas/Auth"}}}}}}}}},"/api/admin/users/{userid}/auth/providers/{provider}":{"delete":{"tags":["Admin"],"summary":"Unlink one OIDC provider from a specific user","description":"`os_admin_user_auth_provider_delete` · minimal role **admin**\n\nUnlink one OIDC provider from a specific user","operationId":"os_admin_user_auth_provider_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"},{"name":"provider","in":"path","required":true,"schema":{"type":"string","description":"provider name"},"description":"provider name"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"unlinked":{"type":"string","description":"Name of the provider that was unlinked"},"auth":{"$ref":"#/components/schemas/Auth"}}}}}}}}},"/api/admin/users/{userid}/activation":{"put":{"tags":["Admin"],"summary":"Activate or deactivate a specific user","description":"`os_admin_user_activation_put` · minimal role **admin**\n\nActivate or deactivate a specific user","operationId":"os_admin_user_activation_put","x-module":"admin","x-access":"admin","parameters":[{"name":"userid","in":"path","required":true,"schema":{"type":"string","description":"user ID"},"description":"user ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean","description":"False deactivates the account, true (or omitted) reactivates it"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/staff/{staffid}/wishes":{"put":{"tags":["Admin"],"summary":"Update the preferences of staff members at the administration level","description":"`os_admin_staff-wishes_put` · minimal role **staff**\n\nUpdate the preferences of staff members at the administration level","operationId":"os_admin_staff-wishes_put","x-module":"admin","x-access":"staff","parameters":[{"name":"staffid","in":"path","required":true,"schema":{"type":"string","description":"Staff ID"},"description":"Staff ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"wishes":{"$ref":"#/components/schemas/Wishes"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/teachers/{teacherid}/wishes":{"put":{"tags":["Admin"],"summary":"Update the preferences of teachers at the administration level","description":"`os_admin_teachers-wishes_put` · minimal role **teacher**\n\nUpdate the preferences of teachers at the administration level","operationId":"os_admin_teachers-wishes_put","x-module":"admin","x-access":"teacher","parameters":[{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"Teacher ID"},"description":"Teacher ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"wishes":{"$ref":"#/components/schemas/WishesTeachers"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/students/{studentid}/placements/{schoolyear}":{"put":{"tags":["Admin"],"summary":"Update the placements (class/group) of a student for a specific school year","description":"`os_admin_student-placements_put` · minimal role **teacher**\n\nUpdate the placements (class/group) of a student for a specific school year","operationId":"os_admin_student-placements_put","x-module":"admin","x-access":"teacher","parameters":[{"name":"schoolyear","in":"path","required":true,"schema":{"type":"string","description":"school year ID"},"description":"school year ID"},{"name":"studentid","in":"path","required":true,"schema":{"type":"string"}}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"placements":{"type":"array","description":"Full placement list replacing the existing data for that school year","items":{"$ref":"#/components/schemas/Placement"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/teachers/{teacherid}/lessons":{"get":{"tags":["Admin"],"summary":"Retrieve the schedule of a specific teacher","description":"`os_admin_teacher-schedules_get` · minimal role **teacher**\n\nRetrieve the schedule of a specific teacher","operationId":"os_admin_teacher-schedules_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"},{"name":"without_teachers","in":"query","required":false,"schema":{"type":"boolean","description":"Set to true to skip the `teachers` details in the response (defaults to false)"},"description":"Set to true to skip the `teachers` details in the response (defaults to false)"},{"name":"without_schoolyears","in":"query","required":false,"schema":{"type":"boolean","description":"Set to true to skip the `school_years` summary (defaults to false)"},"description":"Set to true to skip the `school_years` summary (defaults to false)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"courses":{"description":"List of lessons found for the teacher","type":"array","items":{"$ref":"#/components/schemas/LessonClass"}},"timetables":{"description":"Timetables referenced by the returned lessons","type":"object","additionalProperties":{"$ref":"#/components/schemas/Timetable"}},"teachers":{"description":"Teacher metadata as returned by the schedules module (present unless `without_teachers=true`)","type":"object","additionalProperties":{"type":"object"}},"firstday":{"description":"First day of the week, 0 = Sunday, 1 = Monday","type":"integer","enum":[0,1],"default":1},"levels":{"type":"array","items":{"type":"string"}},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"school_years":{"description":"School years metadata (omitted when `without_schoolyears=true`)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}}}}}}}}}},"/api/admin/roles":{"get":{"tags":["Admin"],"summary":"Retrieve custom roles","description":"`os_admin_customroles_get` · minimal role **admin**\n\nRetrieve custom roles","operationId":"os_admin_customroles_get","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"roles":{"type":"object","x-premiumOnly":true,"properties":{"^[a-z0-9-]+$":{"description":"Custom roles for admin, restricting their access to the platform (requires custom roles option)","type":"object","properties":{"name":{"type":"string"},"exclude_modules":{"type":"array","items":{"type":"string"}},"exclude_endpoints":{"type":"array","items":{"type":"string"}}}}}}}}}}}}},"post":{"tags":["Admin"],"summary":"Create custom role","description":"`os_admin_customroles_post` · minimal role **admin**\n\nCreate custom role","operationId":"os_admin_customroles_post","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"object","properties":{"name":{"type":"string"},"exclude_modules":{"type":"array","items":{"type":"string"}},"exclude_endpoints":{"type":"array","items":{"type":"string"}}},"required":["name"]}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"roleid":{"type":"string","description":"Identifier of the created role"}}}}}}}}},"/api/admin/roles/{roleid}":{"put":{"tags":["Admin"],"summary":"Update custom role","description":"`os_admin_customroles_put` · minimal role **admin**\n\nUpdate custom role","operationId":"os_admin_customroles_put","x-module":"admin","x-access":"admin","parameters":[{"name":"roleid","in":"path","required":true,"schema":{"type":"string","description":"role ID"},"description":"role ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"role":{"type":"object","properties":{"name":{"type":"string"},"exclude_modules":{"type":"array","items":{"type":"string"}},"exclude_endpoints":{"type":"array","items":{"type":"string"}}},"required":["name"]}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"roleid":{"type":"string","description":"Identifier of the updated role"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete custom role","description":"`os_admin_customroles_delete` · minimal role **admin**\n\nDelete custom role","operationId":"os_admin_customroles_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"roleid","in":"path","required":true,"schema":{"type":"string","description":"role ID"},"description":"role ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/subjects/custom":{"get":{"tags":["Admin"],"summary":"Retrieve the list of custom subjects","description":"`os_admin_subjects-custom_get` · minimal role **teacher**\n\nRetrieve the list of custom subjects","operationId":"os_admin_subjects-custom_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"with_countrycount","in":"query","required":false,"schema":{"type":"boolean","description":"Also return the number of available common subjects for the current country"},"description":"Also return the number of available common subjects for the current country"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"subjects":{"description":"Custom subjects (school-owned)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SubjectFull"}},"families":{"description":"Custom subject families (school-owned)","type":"object","additionalProperties":{"$ref":"#/components/schemas/Family"}},"refs":{"description":"Referenced common entities to resolve IDs to display labels","type":"object","properties":{"subjects":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Subject"}},"families":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Family"}}}},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"nocommonsubjects":{"type":"boolean","description":"Indicates whether common country subjects are disabled"},"countrycount":{"type":"integer","description":"Number of reference subjects available for the school's country (only when requested)"}}}}}}}},"post":{"tags":["Admin"],"summary":"Create a new custom subject or bulk import subjects (incremental by default, set replace:true for full replacement)","description":"`os_admin_subjects-custom_post` · minimal role **admin**\n\nCreate a new custom subject or bulk import subjects (incremental by default, set replace:true for full replacement)","operationId":"os_admin_subjects-custom_post","x-module":"admin","x-access":"admin","parameters":[{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"subjects":{"type":"array","description":"Bulk import of custom subjects (incremental by default)","items":{"allOf":[{"$ref":"#/components/schemas/SubjectFull"},{"type":"object","properties":{"id":{"type":"string","description":"Existing subject ID to update (omit to create)"}}}]}},"replace":{"type":"boolean","default":false,"description":"If true, replaces all existing entities. If false/omitted, merges with existing (incremental)."},"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}},"required":["subjects"]},{"allOf":[{"$ref":"#/components/schemas/SubjectFull"},{"type":"object","properties":{"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}}}]}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/subjects/countries/{country}":{"get":{"tags":["Admin"],"summary":"Retrieve the list of subjects for a specific country","description":"`os_admin_subjects_get` · minimal role **teacher**\n\nRetrieve the list of subjects for a specific country","operationId":"os_admin_subjects_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","description":"country code"},"description":"country code"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"subjects":{"description":"Subjects keyed by subject ID for the requested country","type":"object","additionalProperties":{"$ref":"#/components/schemas/SubjectFull"}}}}}}}}}},"/api/admin/subjects/countries/{country}/search/{subject}":{"get":{"tags":["Admin"],"summary":"Search for subjects for a specific country","description":"`os_admin_subjects-search_get` · minimal role **teacher**\n\nSearch for subjects for a specific country","operationId":"os_admin_subjects-search_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","description":"country code"},"description":"country code"},{"name":"subject","in":"path","required":true,"schema":{"type":"string","description":"subject name or code"},"description":"subject name or code"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"results":{"description":"Subjects matching the search string","type":"array","items":{"allOf":[{"$ref":"#/components/schemas/SubjectFull"},{"type":"object","properties":{"id":{"type":"string","description":"Subject identifier"}},"required":["id"]}]}}}}}}}}}},"/api/admin/subjects/countries/{country}/families":{"get":{"tags":["Admin"],"summary":"Retrieve the subject families for a specific country","description":"`os_admin_subjects-families_get` · minimal role **teacher**\n\nRetrieve the subject families for a specific country","operationId":"os_admin_subjects-families_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","description":"country code"},"description":"country code"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"families":{"description":"Subject families defined for the country","type":"object","additionalProperties":{"$ref":"#/components/schemas/Family"}}}}}}}}}},"/api/admin/subjects/countries/{country}/count":{"get":{"tags":["Admin"],"summary":"Retrieve the number of subjects for a specific country","description":"`os_admin_subjects-count_get` · minimal role **teacher**\n\nRetrieve the number of subjects for a specific country","operationId":"os_admin_subjects-count_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","description":"country code"},"description":"country code"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"count":{"type":"integer","description":"Number of subjects available in the requested country"}}}}}}}}},"/api/admin/subjects/colors":{"get":{"tags":["Admin"],"summary":"Retrieve the list of available colors for subjects","description":"`os_admin_subjects-colors_get` · minimal role **admin**\n\nRetrieve the list of available colors for subjects","operationId":"os_admin_subjects-colors_get","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"colors":{"description":"Array of selected colors to use in frontend","type":"array","items":{"description":"Color in hexadecimal (without 0x prefix)","type":"string","examples":["27AE60","9F209F"]}}}}}}}}}},"/api/admin/subjects/custom/{subjectid}":{"put":{"tags":["Admin"],"summary":"Update a specific custom subject","description":"`os_admin_subjects-custom_put` · minimal role **admin**\n\nUpdate a specific custom subject","operationId":"os_admin_subjects-custom_put","x-module":"admin","x-access":"admin","parameters":[{"name":"subjectid","in":"path","required":true,"schema":{"type":"string","description":"subject ID"},"description":"subject ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SubjectFull"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"patch":{"tags":["Admin"],"summary":"Partially update a specific custom subject (only provided fields are modified, null removes a field)","description":"`os_admin_subjects-custom_patch` · minimal role **admin**\n\nPartially update a specific custom subject (only provided fields are modified, null removes a field)","operationId":"os_admin_subjects-custom_patch","x-module":"admin","x-access":"admin","parameters":[{"name":"subjectid","in":"path","required":true,"schema":{"type":"string","description":"subject ID"},"description":"subject ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"allOf":[{"$ref":"#/components/schemas/Subject"},{"type":"object","properties":{"parent":{"description":"Parent subject (another subject)","type":"string"},"family":{"description":"Family of the subject","type":"string"},"color":{"description":"Color (if not defined, will be automatically computed based on name hash)","type":"string"}}}],"description":"Partial custom subject object. Only provided fields are modified; null removes a field."}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a specific custom subject","description":"`os_admin_subjects-custom_delete` · minimal role **admin**\n\nDelete a specific custom subject","operationId":"os_admin_subjects-custom_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"subjectid","in":"path","required":true,"schema":{"type":"string","description":"subject ID"},"description":"subject ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/families/custom":{"get":{"tags":["Admin"],"summary":"Retrieve the list of custom subject families","description":"`os_admin_families-custom_get` · minimal role **teacher**\n\nRetrieve the list of custom subject families","operationId":"os_admin_families-custom_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"with_common","in":"query","required":false,"schema":{"type":"boolean","description":"When true, also returns country/common families under common_families"},"description":"When true, also returns country/common families under common_families"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"families":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Family"}},"common_families":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Family"}}}}}}}}},"post":{"tags":["Admin"],"summary":"Create a new custom subject family or bulk import families (incremental by default, set replace:true for full replacement)","description":"`os_admin_families-custom_post` · minimal role **admin**\n\nCreate a new custom subject family or bulk import families (incremental by default, set replace:true for full replacement)","operationId":"os_admin_families-custom_post","x-module":"admin","x-access":"admin","parameters":[{"name":"checkduplicates","in":"query","required":false,"schema":{"type":"boolean","x-mcp":{"expose":"server-fixed","default":true},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},"description":"Check same-name duplicates before creation. Enabled by default for MCP/assistant."},{"name":"allowduplicate","in":"query","required":false,"schema":{"type":"boolean","description":"Force creation even if a same-name entity exists."},"description":"Force creation even if a same-name entity exists."}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"families":{"type":"array","description":"Bulk import of custom families (incremental by default)","items":{"allOf":[{"$ref":"#/components/schemas/Family"},{"type":"object","properties":{"id":{"type":"string","description":"Existing family ID to update (omit to create)"}}}]}},"replace":{"type":"boolean","default":false,"description":"If true, replaces all existing entities. If false/omitted, merges with existing (incremental)."},"nodoubles":{"type":"boolean","default":true,"description":"If true, avoids creating duplicate entities based on unique fields (code/name)."}},"required":["families"]},{"$ref":"#/components/schemas/Family"}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/families/custom/{familyid}":{"put":{"tags":["Admin"],"summary":"Update a specific custom subject family","description":"`os_admin_families-custom_put` · minimal role **admin**\n\nUpdate a specific custom subject family","operationId":"os_admin_families-custom_put","x-module":"admin","x-access":"admin","parameters":[{"name":"familyid","in":"path","required":true,"schema":{"type":"string","description":"family ID"},"description":"family ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Family"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a specific custom subject family","description":"`os_admin_families-custom_delete` · minimal role **admin**\n\nDelete a specific custom subject family","operationId":"os_admin_families-custom_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"familyid","in":"path","required":true,"schema":{"type":"string","description":"family ID"},"description":"family ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/parameters":{"get":{"tags":["Admin"],"summary":"Retrieve the administration parameters","description":"`os_admin_parameters_get` · minimal role **admin**\n\nRetrieve the administration parameters","operationId":"os_admin_parameters_get","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"allOf":[{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}},{"$ref":"#/components/schemas/SchoolConfig"},{"type":"object","properties":{"school_years":{"description":"School years without holiday details","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}},"logo":{"type":"string","description":"Base64 encoded logo (if configured)"},"translations":{"$ref":"#/components/schemas/Translations"}}}]}}}}}},"put":{"tags":["Admin"],"summary":"Update the administration parameters","description":"`os_admin_parameters_put` · minimal role **admin**\n\nUpdate the administration parameters","operationId":"os_admin_parameters_put","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"allOf":[{"$ref":"#/components/schemas/SchoolConfig"},{"type":"object","properties":{"logo":{"type":["string","null"],"description":"Base64 encoded logo data; set to null to remove"},"logodigest":{"type":"string","description":"Optional checksum to detect logo changes"}}}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/parameters/defaults":{"put":{"tags":["Admin"],"summary":"Update the timetable default parameters at creation","description":"`os_admin_parameters-defaults_put` · minimal role **admin**\n\nUpdate the timetable default parameters at creation","operationId":"os_admin_parameters-defaults_put","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"time_unit":{"description":"Division of the time slot (e.g. 2 with a time_period of 60 enables lessons of 1h30","type":"integer","default":1},"time_period":{"description":"Time slot duration (most of the time 60 = 1 hour)","type":"integer","default":60},"displaymode":{"description":"Defines how the timetable grid is structured in the calendar view. \"hours\": real start/end times (e.g. 09:15–10:10), \"periods\": numbered slots (e.g. 0, 1, 2...), \"agenda\": fixed hourly layout (e.g. 8:00, 9:00, 10:00...), like in calendar apps","type":"string","enum":["hours","periods","agenda"],"default":"hours"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/parameters/timezones":{"get":{"tags":["Admin"],"summary":"Retrieve the list of available timezones","description":"`os_admin_parameters_timezones_get` · minimal role **admin**\n\nRetrieve the list of available timezones","operationId":"os_admin_parameters_timezones_get","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"timezones":{"type":"array","items":{"type":"string"}}}}}}}}}},"/api/admin/parameters/translations/rules":{"get":{"tags":["Admin"],"summary":"Retrieve the translation rules (custom redefinitions)","description":"`os_admin_parameters-translations-rules_get` · minimal role **admin** · **Premium**\n\nRetrieve the translation rules (custom redefinitions)","operationId":"os_admin_parameters-translations-rules_get","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"translationrules":{"type":"array","items":{"$ref":"#/components/schemas/TranslationRule"}}}}}}}}},"put":{"tags":["Admin"],"summary":"Update the translation rules","description":"`os_admin_parameters-translations-rules_put` · minimal role **admin** · **Premium**\n\nUpdate the translation rules","operationId":"os_admin_parameters-translations-rules_put","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"translationrules":{"type":"array","items":{"$ref":"#/components/schemas/TranslationRule"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/parameters/translations/keys":{"get":{"tags":["Admin"],"summary":"Retrieve the customisations of translation keys","description":"`os_admin_parameters-translations-keys_get` · minimal role **admin** · **Premium**\n\nRetrieve the customisations of translation keys","operationId":"os_admin_parameters-translations-keys_get","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"translationrules":{"description":"Map of translation key overrides","type":"object","additionalProperties":{"type":"string"}}}}}}}}},"post":{"tags":["Admin"],"summary":"Create customisations of translation keys","description":"`os_admin_parameters-translations-keys_post` · minimal role **admin** · **Premium**\n\nCreate customisations of translation keys","operationId":"os_admin_parameters-translations-keys_post","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"keys":{"description":"Map of translation keys to override (use an empty string to disable a translation)","type":"object","additionalProperties":{"type":["string","null"]}},"key":{"type":"string","description":"Shortcut to update a single translation key (value taken from `keys` if also provided)"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/schoolyears":{"get":{"tags":["Admin"],"summary":"Retrieve the list of school years","description":"`os_admin_schoolyears_get` · minimal role **teacher**\n\nRetrieve the list of school years","operationId":"os_admin_schoolyears_get","x-module":"admin","x-access":"teacher","parameters":[{"name":"summarize","in":"query","required":false,"schema":{"type":"boolean","description":"If true, only keep basic fields (name and dates)"},"description":"If true, only keep basic fields (name and dates)"},{"name":"without_schoolyears","in":"query","required":false,"schema":{"type":"boolean","description":"Internal use: skip `school_years` population (defaults to false)"},"description":"Internal use: skip `school_years` population (defaults to false)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"school_years":{"description":"School years keyed by ID (contains `week_start`/`week_end` computed server-side)","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}}}}}}}}},"post":{"tags":["Admin"],"summary":"Create a new school year","description":"`os_admin_schoolyear_post` · minimal role **admin**\n\nCreate a new school year","operationId":"os_admin_schoolyear_post","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"Name of the school year","type":"string"},"date_start":{"description":"Start date","type":"string","format":"date"},"date_end":{"description":"End date","type":"string","format":"date"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"uid":{"type":"string","description":"Identifier of the newly created school year"}}}}}}}}},"/api/admin/schoolyears/{schoolyearid}":{"put":{"tags":["Admin"],"summary":"Update a specific school year","description":"`os_admin_schoolyear_put` · minimal role **admin**\n\nUpdate a specific school year","operationId":"os_admin_schoolyear_put","x-module":"admin","x-access":"admin","parameters":[{"name":"schoolyearid","in":"path","required":true,"schema":{"type":"string","description":"school year ID"},"description":"school year ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"name":{"description":"Name of the school year","type":"string"},"date_start":{"description":"Start date","type":"string","format":"date"},"date_end":{"description":"End date","type":"string","format":"date"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"uid":{"type":"string","description":"Identifier of the updated school year"},"school_year":{"$ref":"#/components/schemas/SchoolYear"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a specific school year","description":"`os_admin_schoolyear_delete` · minimal role **admin**\n\nDelete a specific school year","operationId":"os_admin_schoolyear_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"schoolyearid","in":"path","required":true,"schema":{"type":"string","description":"school year ID"},"description":"school year ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/holidays/{country}":{"get":{"tags":["Admin"],"summary":"Retrieve the common holidays for a specific country","description":"`os_admin_schoolyears-common-holidays_get` · minimal role **admin**\n\nRetrieve the common holidays for a specific country","operationId":"os_admin_schoolyears-common-holidays_get","x-module":"admin","x-access":"admin","parameters":[{"name":"country","in":"path","required":true,"schema":{"type":"string","description":"country code"},"description":"country code"},{"name":"dates","in":"query","required":false,"schema":{"type":"string","description":"Optional date range filter (YYYYMMDD-YYYYMMDD)"},"description":"Optional date range filter (YYYYMMDD-YYYYMMDD)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"school_years":{"description":"Common holidays filtered by the provided range","type":"object","additionalProperties":{"$ref":"#/components/schemas/SchoolYear"}}}}}}}}}},"/api/admin/schoolyears/{schoolyearid}/holidays":{"post":{"tags":["Admin"],"summary":"Add a holiday to a specific school year","description":"`os_admin_schoolyear-holiday_post` · minimal role **admin**\n\nAdd a holiday to a specific school year","operationId":"os_admin_schoolyear-holiday_post","x-module":"admin","x-access":"admin","parameters":[{"name":"schoolyearid","in":"path","required":true,"schema":{"type":"string","description":"school year ID"},"description":"school year ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"oneOf":[{"type":"object","properties":{"holidays":{"type":"array","description":"Bulk list of holidays to replace the existing configuration","items":{"$ref":"#/components/schemas/Holiday"}}},"required":["holidays"]},{"$ref":"#/components/schemas/Holiday"}]}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"holidays":{"description":"Updated holidays for the school year","type":"array","items":{"$ref":"#/components/schemas/Holiday"}}}}}}}}}},"/api/admin/schoolyears/{schoolyearid}/holidays/{holidayid}":{"put":{"tags":["Admin"],"summary":"Update a specific holiday of a school year","description":"`os_admin_schoolyear-holiday_put` · minimal role **admin**\n\nUpdate a specific holiday of a school year","operationId":"os_admin_schoolyear-holiday_put","x-module":"admin","x-access":"admin","parameters":[{"name":"schoolyearid","in":"path","required":true,"schema":{"type":"string","description":"school year ID"},"description":"school year ID"},{"name":"holidayid","in":"path","required":true,"schema":{"type":"string","description":"holiday ID"},"description":"holiday ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/Holiday"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"holidays":{"description":"Updated holidays for the school year","type":"array","items":{"$ref":"#/components/schemas/Holiday"}}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a specific holiday of a school year","description":"`os_admin_schoolyear-holiday_delete` · minimal role **admin**\n\nDelete a specific holiday of a school year","operationId":"os_admin_schoolyear-holiday_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"schoolyearid","in":"path","required":true,"schema":{"type":"string","description":"school year ID"},"description":"school year ID"},{"name":"holidayid","in":"path","required":true,"schema":{"type":"string","description":"holiday ID"},"description":"holiday ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"holidays":{"description":"Remaining holidays for the school year","type":"array","items":{"$ref":"#/components/schemas/Holiday"}}}}}}}}}},"/api/admin/schoolyears/{schoolyearid}/altweeks":{"put":{"tags":["Admin"],"summary":"Update the configuration of alternating weeks for a specific school year","description":"`os_admin_schoolyear-altweeks_put` · minimal role **admin**\n\nUpdate the configuration of alternating weeks for a specific school year","operationId":"os_admin_schoolyear-altweeks_put","x-module":"admin","x-access":"admin","parameters":[{"name":"schoolyearid","in":"path","required":true,"schema":{"type":"string","description":"school year ID"},"description":"school year ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"altweeks":{"description":"Array of alternate weeks to determine wether to change the alterations at some point, mainly because of holidays","type":"array","items":{"type":"integer"}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/export/json":{"post":{"tags":["Admin"],"summary":"Launch a JSON export of the complete account in database (through Ajax call)","description":"`os_admin_export-json_post` · minimal role **admin**\n\nLaunch a JSON export of the complete account in database (through Ajax call)","operationId":"os_admin_export-json_post","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"get":{"tags":["Admin"],"summary":"Launch a JSON export of the complete account in database (direct link)","description":"`os_admin_export-json_get` · minimal role **admin**\n\nLaunch a JSON export of the complete account in database (direct link)","operationId":"os_admin_export-json_get","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/export/asc":{"get":{"tags":["Admin"],"summary":"Export timetable(s) to an aSc Timetables 2012 XML file","description":"`os_admin_export-asc_get` · minimal role **admin**\n\nExport timetable(s) to an aSc Timetables 2012 XML file","operationId":"os_admin_export-asc_get","x-module":"admin","x-access":"admin","parameters":[{"name":"timetable_id","in":"query","required":false,"schema":{"type":"string","description":"Explicit timetable id (optional)"},"description":"Explicit timetable id (optional)"},{"name":"schoolyear","in":"query","required":false,"schema":{"type":"string","description":"School year id (optional, default=current)"},"description":"School year id (optional, default=current)"},{"name":"all","in":"query","required":false,"schema":{"type":"boolean","description":"Export all active timetables for the school year (optional)"},"description":"Export all active timetables for the school year (optional)"},{"name":"name","in":"query","required":false,"schema":{"type":"string","description":"Export filename (optional)"},"description":"Export filename (optional)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"type":"string","description":"XML content"}}}}}}}},"/api/admin/export/udt":{"get":{"tags":["Admin"],"summary":"Export a timetable to the UDT (UnDeuxTemps) DBF format read by Aplim/Charlemagne (ZIP of UDTCOURS/UDTREGR/UDTREM)","description":"`os_admin_export-udt_get` · minimal role **admin**\n\nExport a timetable to the UDT (UnDeuxTemps) DBF format read by Aplim/Charlemagne (ZIP of UDTCOURS/UDTREGR/UDTREM)","operationId":"os_admin_export-udt_get","x-module":"admin","x-access":"admin","parameters":[{"name":"timetable_id","in":"query","required":false,"schema":{"type":"string","description":"Explicit timetable id (optional)"},"description":"Explicit timetable id (optional)"},{"name":"schoolyear","in":"query","required":false,"schema":{"type":"string","description":"School year id (optional, default=current)"},"description":"School year id (optional, default=current)"},{"name":"datesrange","in":"query","required":false,"schema":{"type":"string","description":"Week to resolve as a real dated schedule, format YYYYMMDD-YYYYMMDD (optional; omit to export the generic-week structure)"},"description":"Week to resolve as a real dated schedule, format YYYYMMDD-YYYYMMDD (optional; omit to export the generic-week structure)"},{"name":"name","in":"query","required":false,"schema":{"type":"string","description":"Inner folder name to paste into Charlemagne (optional; e.g. a week label)"},"description":"Inner folder name to paste into Charlemagne (optional; e.g. a week label)"},{"name":"filename","in":"query","required":false,"schema":{"type":"string","description":"Download filename for the ZIP (optional; a timestamped name is generated otherwise)"},"description":"Download filename for the ZIP (optional; a timestamped name is generated otherwise)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"type":"string","description":"ZIP archive (application/zip)"}}}}}}}},"/api/admin/import/json":{"post":{"tags":["Admin"],"summary":"os_admin_import-json_post","description":"`os_admin_import-json_post` · minimal role **superadmin**","operationId":"os_admin_import-json_post","x-module":"admin","x-access":"superadmin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/import/asc":{"post":{"tags":["Admin"],"summary":"Import data from an AsC Timetables file","description":"`os_admin_import-asc_post` · minimal role **admin**\n\nImport data from an AsC Timetables file","operationId":"os_admin_import-asc_post","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/import/udt":{"post":{"tags":["Admin"],"summary":"Import data from a UDT (UnDeuxTemps) DBF export (Aplim/Charlemagne); body carries the 3 tables as latin-1 strings","description":"`os_admin_import-udt_post` · minimal role **admin**\n\nImport data from a UDT (UnDeuxTemps) DBF export (Aplim/Charlemagne); body carries the 3 tables as latin-1 strings","operationId":"os_admin_import-udt_post","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/import/sts":{"post":{"tags":["Admin"],"summary":"Import data from an STS file","description":"`os_admin_import-sts_post` · minimal role **admin**\n\nImport data from an STS file","operationId":"os_admin_import-sts_post","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/import/siecle":{"post":{"tags":["Admin"],"summary":"Import data from a Siecle file","description":"`os_admin_import-siecle_post` · minimal role **admin**\n\nImport data from a Siecle file","operationId":"os_admin_import-siecle_post","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/config/extsync":{"get":{"tags":["Admin"],"summary":"Get external sync configuration (all systems)","description":"`os_admin_config-extsync_get` · minimal role **admin** · **Premium**\n\nGet external sync configuration (all systems)","operationId":"os_admin_config-extsync_get","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Admin"],"summary":"Update external sync configuration (all systems)","description":"`os_admin_config-extsync_put` · minimal role **admin** · **Premium**\n\nUpdate external sync configuration (all systems)","operationId":"os_admin_config-extsync_put","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"config":{"$ref":"#/components/schemas/SchoolConfigExtsync"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/config/extsync/sync":{"put":{"tags":["Admin"],"summary":"Update synchronization settings (all entities)","description":"`os_admin_config-extsync-sync_put` · minimal role **admin** · **Premium**\n\nUpdate synchronization settings (all entities)","operationId":"os_admin_config-extsync-sync_put","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"sync":{"$ref":"#/components/schemas/SchoolConfigExtsyncSync"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/config/extsync/export":{"put":{"tags":["Admin"],"summary":"Update export settings (all entities)","description":"`os_admin_config-extsync-export_put` · minimal role **admin** · **Premium**\n\nUpdate export settings (all entities)","operationId":"os_admin_config-extsync-export_put","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"export":{"$ref":"#/components/schemas/SchoolConfigExtsyncExport"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/config/extsync/schedules":{"put":{"tags":["Admin"],"summary":"Update schedules synchronization settings","description":"`os_admin_config-extsync-schedules_put` · minimal role **admin** · **Premium**\n\nUpdate schedules synchronization settings","operationId":"os_admin_config-extsync-schedules_put","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"schedules":{"$ref":"#/components/schemas/SchoolConfigExtsyncSchedules"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/config/extsync/systems/{system}":{"get":{"tags":["Admin"],"summary":"Get configuration for a specific external system","description":"`os_admin_config-extsync-system_get` · minimal role **admin** · **Premium**\n\nGet configuration for a specific external system","operationId":"os_admin_config-extsync-system_get","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Admin"],"summary":"Update configuration for a specific external system","description":"`os_admin_config-extsync-system_put` · minimal role **admin** · **Premium**\n\nUpdate configuration for a specific external system","operationId":"os_admin_config-extsync-system_put","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchoolConfigExtsyncSystem"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/extsync/{system}/mappings":{"get":{"tags":["Admin"],"summary":"Get all ExtSync entity mappings for the selected external system","description":"`os_admin_extsync-mappings_get` · minimal role **admin** · **Premium**\n\nGet all ExtSync entity mappings for the selected external system","operationId":"os_admin_extsync-mappings_get","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"mappings":{"$ref":"#/components/schemas/SchoolConfigExtsyncMappings"}}}}}}}},"put":{"tags":["Admin"],"summary":"Store all ExtSync entity mappings for the selected external system","description":"`os_admin_extsync-mappings_put` · minimal role **admin** · **Premium**\n\nStore all ExtSync entity mappings for the selected external system","operationId":"os_admin_extsync-mappings_put","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mappings":{"type":"object","description":"ExtSync mappings input accepted by the admin API","additionalProperties":{"type":"object","description":"ExtSync mapping map input accepted by the admin API for a single mapping key","additionalProperties":{"oneOf":[{"type":"string","description":"External ID shortcut"},{"type":"null","description":"Ignore this local value/entity"},{"$ref":"#/components/schemas/SchoolConfigExtsyncMappingEntry"}]}}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"mappings":{"$ref":"#/components/schemas/SchoolConfigExtsyncMappings"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete all or selected ExtSync entity mappings for the selected external system","description":"`os_admin_extsync-mappings_delete` · minimal role **admin** · **Premium**\n\nDelete all or selected ExtSync entity mappings for the selected external system","operationId":"os_admin_extsync-mappings_delete","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"entities":{"type":"array","description":"Optional entity mapping keys to delete. Omit this field to delete all entity mappings.","items":{"type":"string","enum":["subjects","teachers","classes","groups","classrooms"]}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/extsync/{system}/sync":{"post":{"tags":["Admin"],"summary":"Launch immediate schedules synchronization for the selected external system","description":"`os_admin_extsync-sync_post` · minimal role **admin** · **Premium**\n\nLaunch immediate schedules synchronization for the selected external system","operationId":"os_admin_extsync-sync_post","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/extsync/{system}/datasets/{dataset}":{"post":{"tags":["Admin"],"summary":"Fetch, validate, preview and cache a raw connector dataset snapshot for the selected external system","description":"`os_admin_extsync-dataset_post` · minimal role **admin** · **Premium**\n\nFetch, validate, preview and cache a raw connector dataset snapshot for the selected external system","operationId":"os_admin_extsync-dataset_post","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"dataset","in":"path","required":true,"schema":{"type":"string","description":"Connector-specific dataset key. For Aurion this matches the favori type, for example matieres, cours, intervenants, groupes, ressources, interventions or statuts_intervention."},"description":"Connector-specific dataset key. For Aurion this matches the favori type, for example matieres, cours, intervenants, groupes, ressources, interventions or statuts_intervention."},{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"configuration":{"type":"object","description":"Connector-specific configuration to use for this raw dataset fetch"},"dataset_id":{"type":"string","description":"Connector-specific dataset identifier. For Aurion this is the WebAurion favori ID. Send an empty string to clear the cached snapshot for this dataset."}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/extsync/{system}/import":{"put":{"tags":["Admin"],"summary":"Run the initial import flow for the selected external system","description":"`os_admin_extsync-import_put` · minimal role **admin** · **Premium**\n\nRun the initial import flow for the selected external system","operationId":"os_admin_extsync-import_put","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"type":"object","description":"Connector-specific initial import configuration. For Aurion this is the WebAurion configuration payload including favori_interventions."}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/extsync/{system}/mappings/{mapping}":{"get":{"tags":["Admin"],"summary":"Get ExtSync value mappings for the selected external system","description":"`os_admin_extsync-mapping_get` · minimal role **admin** · **Premium**\n\nGet ExtSync value mappings for the selected external system","operationId":"os_admin_extsync-mapping_get","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"mapping","in":"path","required":true,"schema":{"enum":["subjects","teachers","classes","groups","classrooms","status"],"description":"Mapping key"},"description":"Mapping key"},{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"mappings":{"$ref":"#/components/schemas/SchoolConfigExtsyncMappingMap"}}}}}}}},"put":{"tags":["Admin"],"summary":"Store ExtSync mappings for the selected external system and mapping key","description":"`os_admin_extsync-mapping_put` · minimal role **admin** · **Premium**\n\nStore ExtSync mappings for the selected external system and mapping key","operationId":"os_admin_extsync-mapping_put","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"mapping","in":"path","required":true,"schema":{"enum":["subjects","teachers","classes","groups","classrooms","status"],"description":"Mapping key"},"description":"Mapping key"},{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"mappings":{"type":"object","description":"ExtSync mapping map input accepted by the admin API for a single mapping key","additionalProperties":{"oneOf":[{"type":"string","description":"External ID shortcut"},{"type":"null","description":"Ignore this local value/entity"},{"$ref":"#/components/schemas/SchoolConfigExtsyncMappingEntry"}]}}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"mappings":{"$ref":"#/components/schemas/SchoolConfigExtsyncMappingMap"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete ExtSync mappings for the selected external system and mapping key","description":"`os_admin_extsync-mapping_delete` · minimal role **admin** · **Premium**\n\nDelete ExtSync mappings for the selected external system and mapping key","operationId":"os_admin_extsync-mapping_delete","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[{"name":"mapping","in":"path","required":true,"schema":{"enum":["subjects","teachers","classes","groups","classrooms","status"],"description":"Mapping key"},"description":"Mapping key"},{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/export/aurion/pivot":{"get":{"tags":["Admin"],"summary":"Generate Aurion XML Pivot export","description":"`os_admin_export-aurion-pivot_get` · minimal role **admin** · **Premium**\n\nGenerate Aurion XML Pivot export","operationId":"os_admin_export-aurion-pivot_get","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"post":{"tags":["Admin"],"summary":"Generate Aurion XML Pivot export and send it to WebAurion for synchronization","description":"`os_admin_export-aurion-pivot_post` · minimal role **admin** · **Premium**\n\nGenerate Aurion XML Pivot export and send it to WebAurion for synchronization","operationId":"os_admin_export-aurion-pivot_post","x-module":"admin","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/snapshots":{"get":{"tags":["Admin"],"summary":"Retrieve the list of snapshots","description":"`os_admin_snapshots_get` · minimal role **admin**\n\nRetrieve the list of snapshots","operationId":"os_admin_snapshots_get","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"post":{"tags":["Admin"],"summary":"Create a new snapshot","description":"`os_admin_snapshots_post` · minimal role **admin**\n\nCreate a new snapshot","operationId":"os_admin_snapshots_post","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Admin"],"summary":"Update a snapshot","description":"`os_admin_snapshots_put` · minimal role **admin**\n\nUpdate a snapshot","operationId":"os_admin_snapshots_put","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/snapshots/{snapshot}":{"get":{"tags":["Admin"],"summary":"Retrieve a specific snapshot","description":"`os_admin_snapshots-snapshot_get` · minimal role **admin**\n\nRetrieve a specific snapshot","operationId":"os_admin_snapshots-snapshot_get","x-module":"admin","x-access":"admin","parameters":[{"name":"snapshot","in":"path","required":true,"schema":{"type":"string","description":"snapshot ID"},"description":"snapshot ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Admin"],"summary":"Update a specific snapshot","description":"`os_admin_snapshots-snapshot_put` · minimal role **admin**\n\nUpdate a specific snapshot","operationId":"os_admin_snapshots-snapshot_put","x-module":"admin","x-access":"admin","parameters":[{"name":"snapshot","in":"path","required":true,"schema":{"type":"string","description":"snapshot ID"},"description":"snapshot ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Admin"],"summary":"Delete a specific snapshot","description":"`os_admin_snapshots-snapshot_delete` · minimal role **admin**\n\nDelete a specific snapshot","operationId":"os_admin_snapshots-snapshot_delete","x-module":"admin","x-access":"admin","parameters":[{"name":"snapshot","in":"path","required":true,"schema":{"type":"string","description":"snapshot ID"},"description":"snapshot ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"post":{"tags":["Admin"],"summary":"Perform an action on a specific snapshot","description":"`os_admin_snapshots-snapshot_post` · minimal role **admin**\n\nPerform an action on a specific snapshot","operationId":"os_admin_snapshots-snapshot_post","x-module":"admin","x-access":"admin","parameters":[{"name":"snapshot","in":"path","required":true,"schema":{"type":"string","description":"snapshot ID"},"description":"snapshot ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/logs":{"get":{"tags":["Admin"],"summary":"Retrieve logs","description":"`os_admin_logs_get` · minimal role **admin**\n\nRetrieve logs","operationId":"os_admin_logs_get","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/repair":{"post":{"tags":["Admin"],"summary":"os_admin_repair_post","description":"`os_admin_repair_post` · minimal role **superadmin**","operationId":"os_admin_repair_post","x-module":"admin","x-access":"superadmin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/backups":{"get":{"tags":["Admin"],"summary":"os_admin_backups_get","description":"`os_admin_backups_get` · minimal role **superadmin**","operationId":"os_admin_backups_get","x-module":"admin","x-access":"superadmin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/backups/{subaction}":{"post":{"tags":["Admin"],"summary":"os_admin_backup_post","description":"`os_admin_backup_post` · minimal role **superadmin**","operationId":"os_admin_backup_post","x-module":"admin","x-access":"superadmin","parameters":[{"name":"subaction","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/jobs":{"get":{"tags":["Admin"],"summary":"os_admin_jobs_get","description":"`os_admin_jobs_get` · minimal role **superadmin**","operationId":"os_admin_jobs_get","x-module":"admin","x-access":"superadmin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Admin"],"summary":"os_admin_jobs_put","description":"`os_admin_jobs_put` · minimal role **superadmin**","operationId":"os_admin_jobs_put","x-module":"admin","x-access":"superadmin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Admin"],"summary":"os_admin_jobs_delete","description":"`os_admin_jobs_delete` · minimal role **superadmin**","operationId":"os_admin_jobs_delete","x-module":"admin","x-access":"superadmin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/search":{"post":{"tags":["Search"],"summary":"Global free-text search across the school document. Splits the query into words (case- and accent-insensitive) and returns the JSON paths where every word was found. Powers the application's global search box. For AI-oriented entity resolution use /api/search/entity; for filtered, projected and paginated structured queries use /api/search/query.","description":"`os_search_string_post` · minimal role **admin**\n\nGlobal free-text search across the school document. Splits the query into words (case- and accent-insensitive) and returns the JSON paths where every word was found. Powers the application's global search box. For AI-oriented entity resolution use /api/search/entity; for filtered, projected and paginated structured queries use /api/search/query.","operationId":"os_search_string_post","x-module":"search","x-access":"admin","parameters":[{"name":"stringtosearch","in":"query","required":false,"schema":{"type":"string","description":"Free-text query. Multiple space-separated words are matched independently (all must be found on a given path); matching is case- and accent-insensitive.","x-mcp":{"expose":"required"}},"description":"Free-text query. Multiple space-separated words are matched independently (all must be found on a given path); matching is case- and accent-insensitive."},{"name":"actions","in":"query","required":false,"schema":{"type":"array","description":"Optional disambiguation rules. A rule keeps a path even when some query words are absent from it, provided that path accounts for those words and includes the expected entity keys.","items":{"type":"object","properties":{"words":{"type":"array","items":{"type":"string"},"description":"Query words this rule accounts for"},"keys":{"type":"array","items":{"type":"string"},"description":"Entity keys (path segment types) the matched path must include"}}},"x-mcp":{"expose":"optional"}},"description":"Optional disambiguation rules. A rule keeps a path even when some query words are absent from it, provided that path accounts for those words and includes the expected entity keys."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Always true when the request succeeded"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"foundpaths":{"type":"array","description":"One entry per matching location. Each entry is an ordered array of path segments, from the document root down to the match.","items":{"type":"array","items":{"type":"object","properties":{"key":{"type":"string","description":"Segment type (e.g. classes, teachers, timetables)"},"id":{"type":"string","description":"Identifier of the entity at this segment, when applicable"},"match":{"type":"object","description":"Map of matched query word to the field and value that matched.","additionalProperties":{"type":"object","properties":{"key":{"type":"string","description":"Field that matched"},"value":{"description":"Value that matched"}}}}}}}}}}}}}}}},"/api/search/entity":{"post":{"tags":["Search"],"summary":"Advanced AI-friendly entity search with intelligent fuzzy matching. Automatically handles accent/diacritic normalization (latinization), supports approximate matching with configurable similarity threshold using Dice coefficient, and generates multiple name combinations for people (first+last, last+first, with middle names, etc.). Returns rich contextual information including JSON paths to help locate entities within the school data structure. Perfect for AI assistants to resolve user queries like '6A' → '6eA class' or 'Martine Dupont' → 'Martine Dupond teacher'. Prioritizes exact matches, falls back to similarity scoring when no perfect match exists. For plain free-text search use /api/search; for filtered, projected and paginated structured queries use /api/search/query.","description":"`os_search_entity_post` · minimal role **admin**\n\nAdvanced AI-friendly entity search with intelligent fuzzy matching. Automatically handles accent/diacritic normalization (latinization), supports approximate matching with configurable similarity threshold using Dice coefficient, and generates multiple name combinations for people (first+last, last+first, with middle names, etc.). Returns rich contextual information including JSON paths to help locate entities within the school data structure. Perfect for AI assistants to resolve user queries like '6A' → '6eA class' or 'Martine Dupont' → 'Martine Dupond teacher'. Prioritizes exact matches, falls back to similarity scoring when no perfect match exists. For plain free-text search use /api/search; for filtered, projected and paginated structured queries use /api/search/query.","operationId":"os_search_entity_post","x-module":"search","x-access":"admin","parameters":[{"name":"query","in":"query","required":false,"schema":{"oneOf":[{"type":"string","description":"Single search term (e.g., '6A', 'John Doe', 'science lab')"},{"type":"array","items":{"type":"string"},"description":"Multiple search terms (e.g., ['6A', '5B'] or ['John*', 'Marie?'])"}],"description":"Search term(s). Supports wildcards: * (any chars), ? (single char). Single string or array of strings for multiple searches.","x-mcp":{"expose":"required"}},"description":"Search term(s). Supports wildcards: * (any chars), ? (single char). Single string or array of strings for multiple searches."},{"name":"entity_types","in":"query","required":false,"schema":{"type":"array","items":{"type":"string","enum":["classes","teachers","students","classrooms","sites","groups","school_years","subjects","users"]},"description":"Types of entities to search in. Defaults to all types if not specified","x-mcp":{"expose":"optional"}},"description":"Types of entities to search in. Defaults to all types if not specified"},{"name":"threshold","in":"query","required":false,"schema":{"type":"number","minimum":0,"maximum":1,"default":0.7,"description":"Minimum similarity score for approximate matches (0-1)","x-mcp":{"expose":"optional"}},"description":"Minimum similarity score for approximate matches (0-1)"},{"name":"max_results","in":"query","required":false,"schema":{"type":"integer","minimum":1,"maximum":1000,"default":10,"description":"Maximum number of results to return","x-mcp":{"expose":"optional"}},"description":"Maximum number of results to return"},{"name":"match_mode","in":"query","required":false,"schema":{"type":"string","enum":["content","id","both"],"default":"content","description":"Matching strategy: 'content' searches text fields, 'id' does exact ID lookup, 'both' tries ID first then fallback to content","x-mcp":{"expose":"optional"}},"description":"Matching strategy: 'content' searches text fields, 'id' does exact ID lookup, 'both' tries ID first then fallback to content"},{"name":"partial_match","in":"query","required":false,"schema":{"type":"boolean","default":false,"description":"Enable partial substring matching (e.g., 'anglais' matches 'LV1 Anglais 2'). Improves recall for partial queries.","x-mcp":{"expose":"optional"}},"description":"Enable partial substring matching (e.g., 'anglais' matches 'LV1 Anglais 2'). Improves recall for partial queries."},{"name":"search_fields","in":"query","required":false,"schema":{"type":"array","items":{"type":"string","enum":["name","first_name","last_name","middle_name","virtual_name","description","code","comment","label","levels","type","types","birthdate","login","email","phone","idnumber","holidays"]},"description":"Specific fields to search in. Defaults to all searchable fields: name, first_name, last_name, middle_name, virtual_name, description, code, comment, label, levels, type, types, birthdate, login, email, phone, idnumber, holidays","x-mcp":{"expose":"optional"}},"description":"Specific fields to search in. Defaults to all searchable fields: name, first_name, last_name, middle_name, virtual_name, description, code, comment, label, levels, type, types, birthdate, login, email, phone, idnumber, holidays"},{"name":"where","in":"query","required":false,"schema":{"description":"Structured filter clause using MongoDB-style operators. Field names support dot-path notation for parent context (e.g., 'sites.name'). Values can be direct (implies $eq) or objects with operators. Multiple operators on same field = implicit AND.","allOf":[{"$ref":"#/components/schemas/WhereClause"}]},"description":"Structured filter clause using MongoDB-style operators. Field names support dot-path notation for parent context (e.g., 'sites.name'). Values can be direct (implies $eq) or objects with operators. Multiple operators on same field = implicit AND.","examples":{"simpleEquality":{"summary":"Simple equality","value":"{\"capacity\":30}"},"comparison":{"summary":"Comparison operators","value":"{\"capacity\":{\"$gte\":20,\"$lte\":50}}"},"inList":{"summary":"Value in list","value":"{\"level\":{\"$in\":[\"L1\",\"L2\",\"L3\"]}}"},"exists":{"summary":"Field existence","value":"{\"virtual_name\":{\"$exists\":true}}"},"regex":{"summary":"Regular expression (case-insensitive)","value":"{\"name\":{\"$regex\":\"^lab\"}}"},"contains":{"summary":"String/array contains","value":"{\"name\":{\"$contains\":\"chimie\"}}"},"like":{"summary":"Dice-based fuzzy text match ignoring accents/punctuation","value":"{\"city\":{\"$like\":\"ivry sur seine\"}}"},"dotPath":{"summary":"Dot-path with parent context","value":"{\"capacity\":{\"$gte\":20},\"sites.name\":{\"$regex\":\"campus\"}}"},"logicalOr":{"summary":"Logical OR","value":"{\"$or\":[{\"capacity\":{\"$gte\":50}},{\"specialisation\":\"chemistry\"}]}"},"complex":{"summary":"Complex nested logic","value":"{\"$and\":[{\"capacity\":{\"$gte\":20}},{\"$or\":[{\"specialisation\":\"chemistry\"},{\"name\":{\"$contains\":\"lab\"}}]}]}"}}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"results":{"type":"array","description":"Array of matching entities","items":{"type":"object","properties":{"id":{"type":"string","description":"Entity ID"},"type":{"type":"string","description":"Entity type (classes, teachers, etc.)"},"name":{"type":"string","description":"Display name of the entity"},"matched_field":{"type":"string","description":"Field that matched the query"},"matched_value":{"type":"string","description":"Actual value that matched"},"matched_query":{"type":"string","description":"Which query term from the array matched (when using multiple queries)"},"score":{"type":"number","description":"Similarity score (0-1, where 1 is perfect match)"},"context":{"type":"object","description":"Contextual information about where the entity was found","additionalProperties":{"type":"object","properties":{"id":{"type":"string"},"name":{"type":"string"}}}}}}},"perfect_matches":{"type":"boolean","description":"True if at least one result has a perfect match (score = 1.0)"},"total":{"type":"integer","description":"Number of results returned (limited by max_results)"},"total_perfect_matches":{"type":"integer","description":"Total number of perfect matches found"},"total_approximate_matches":{"type":"integer","description":"Total number of approximate matches found"},"total_found":{"type":"integer","description":"Total number of matches found (perfect + approximate)"},"truncated":{"type":"boolean","description":"True if results were limited by max_results parameter"},"truncated_perfect_matches":{"type":"integer","description":"Number of perfect matches that were truncated due to max_results limit"},"truncated_approximate_matches":{"type":"integer","description":"Number of approximate matches that were truncated due to max_results limit"}}}}}}}}},"/api/search/query":{"post":{"tags":["Search"],"summary":"Advanced query orchestrator with Mango / MongoDB-style filtering. Calls an internal API endpoint, then applies a structured `where` filter ($eq, $ne, $gt/$gte/$lt/$lte, $in/$nin, $exists, $regex, $contains, $like, $and/$or/$not — with dot-path field access), plus field projection, sorting and pagination on the results. Designed for complex cross-module queries that would otherwise require multiple tool calls or produce too much data for an LLM. Supports computed pseudo-fields like _count for array lengths. For plain free-text search use /api/search; to resolve a name to an entity use /api/search/entity.","description":"`os_search_query_post` · minimal role **admin**\n\nAdvanced query orchestrator with Mango / MongoDB-style filtering. Calls an internal API endpoint, then applies a structured `where` filter ($eq, $ne, $gt/$gte/$lt/$lte, $in/$nin, $exists, $regex, $contains, $like, $and/$or/$not — with dot-path field access), plus field projection, sorting and pagination on the results. Designed for complex cross-module queries that would otherwise require multiple tool calls or produce too much data for an LLM. Supports computed pseudo-fields like _count for array lengths. For plain free-text search use /api/search; to resolve a name to an entity use /api/search/entity.","operationId":"os_search_query_post","x-module":"search","x-access":"admin","parameters":[{"name":"call","in":"query","required":false,"schema":{"type":"string","description":"Callback name of the internal endpoint to call (e.g. 'os_schedules_dates_get', 'os_absences_get'). Must be an existing callback in routes.json.","x-mcp":{"expose":"required"}},"description":"Callback name of the internal endpoint to call (e.g. 'os_schedules_dates_get', 'os_absences_get'). Must be an existing callback in routes.json."},{"name":"params","in":"query","required":false,"schema":{"type":"object","description":"Parameters to pass to the internal endpoint call (as if they were query parameters of the original endpoint). For os_schedules_dates_get, this includes 'datesrange', 'filter', 'with_timetables', etc.","x-mcp":{"expose":"required"}},"description":"Parameters to pass to the internal endpoint call (as if they were query parameters of the original endpoint). For os_schedules_dates_get, this includes 'datesrange', 'filter', 'with_timetables', etc."},{"name":"extract_path","in":"query","required":false,"schema":{"type":"string","description":"Optional dot-path to extract results from (e.g., 'schedules.classes', 'results', 'absences.teachers'). If omitted, auto-detects from result structure (schedules → flattens all entity types, results → uses array as-is, other → generic object flattening).","x-mcp":{"expose":"optional"}},"description":"Optional dot-path to extract results from (e.g., 'schedules.classes', 'results', 'absences.teachers'). If omitted, auto-detects from result structure (schedules → flattens all entity types, results → uses array as-is, other → generic object flattening).","example":"schedules.classes, results, absences.teachers, timetables"},{"name":"project","in":"query","required":false,"schema":{"type":"array","items":{"type":"string"},"description":"List of fields to include in results (field projection). Reduces payload. If omitted, all fields are returned. Supports dot-paths.","x-mcp":{"expose":"optional"}},"description":"List of fields to include in results (field projection). Reduces payload. If omitted, all fields are returned. Supports dot-paths."},{"name":"sort","in":"query","required":false,"schema":{"type":"object","description":"Sort results by field. Key = field name (supports _count.fieldname for array length), value = 'asc' or 'desc'. Single field sort only.","x-mcp":{"expose":"optional"}},"description":"Sort results by field. Key = field name (supports _count.fieldname for array length), value = 'asc' or 'desc'. Single field sort only."},{"name":"limit","in":"query","required":false,"schema":{"type":"integer","minimum":1,"description":"Maximum number of results to return after filtering and sorting.","x-mcp":{"expose":"optional"}},"description":"Maximum number of results to return after filtering and sorting."},{"name":"offset","in":"query","required":false,"schema":{"type":"integer","minimum":0,"default":0,"description":"Number of results to skip (for pagination).","x-mcp":{"expose":"optional"}},"description":"Number of results to skip (for pagination)."},{"name":"where","in":"query","required":false,"schema":{"description":"Structured filter clause using MongoDB-style operators. Field names support dot-path notation for parent context (e.g., 'sites.name'). Values can be direct (implies $eq) or objects with operators. Multiple operators on same field = implicit AND.","allOf":[{"$ref":"#/components/schemas/WhereClause"}]},"description":"Structured filter clause using MongoDB-style operators. Field names support dot-path notation for parent context (e.g., 'sites.name'). Values can be direct (implies $eq) or objects with operators. Multiple operators on same field = implicit AND.","examples":{"simpleEquality":{"summary":"Simple equality","value":"{\"capacity\":30}"},"comparison":{"summary":"Comparison operators","value":"{\"capacity\":{\"$gte\":20,\"$lte\":50}}"},"inList":{"summary":"Value in list","value":"{\"level\":{\"$in\":[\"L1\",\"L2\",\"L3\"]}}"},"exists":{"summary":"Field existence","value":"{\"virtual_name\":{\"$exists\":true}}"},"regex":{"summary":"Regular expression (case-insensitive)","value":"{\"name\":{\"$regex\":\"^lab\"}}"},"contains":{"summary":"String/array contains","value":"{\"name\":{\"$contains\":\"chimie\"}}"},"like":{"summary":"Dice-based fuzzy text match ignoring accents/punctuation","value":"{\"city\":{\"$like\":\"ivry sur seine\"}}"},"dotPath":{"summary":"Dot-path with parent context","value":"{\"capacity\":{\"$gte\":20},\"sites.name\":{\"$regex\":\"campus\"}}"},"logicalOr":{"summary":"Logical OR","value":"{\"$or\":[{\"capacity\":{\"$gte\":50}},{\"specialisation\":\"chemistry\"}]}"},"complex":{"summary":"Complex nested logic","value":"{\"$and\":[{\"capacity\":{\"$gte\":20}},{\"$or\":[{\"specialisation\":\"chemistry\"},{\"name\":{\"$contains\":\"lab\"}}]}]}"}}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Always true if request succeeded"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"results":{"type":"array","description":"Array of result items after filtering, sorting, and projection","items":{}},"meta":{"type":"object","properties":{"call":{"type":"string","description":"The callback that was called"},"total_raw":{"type":"integer","description":"Total items before filtering"},"total_filtered":{"type":"integer","description":"Total items after where filter"},"total_returned":{"type":"integer","description":"Number of items returned after offset/limit"},"offset":{"type":"integer","description":"Offset applied"},"limit":{"type":"integer","description":"Limit applied"}}}}}}}}}}},"/api/user/locale":{"put":{"tags":["User"],"summary":"Update the user's locale","description":"`os_user_locale_put` · minimal role **admin**\n\nUpdate the user's locale","operationId":"os_user_locale_put","x-module":"user","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/user/keep-alive":{"get":{"tags":["User"],"summary":"Keep the user session alive","description":"`os_user_keep-alive_get` · minimal role **admin**\n\nKeep the user session alive","operationId":"os_user_keep-alive_get","x-module":"user","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/user/ping":{"get":{"tags":["User"],"summary":"Check if the user session is active","description":"`os_user_ping_get` · minimal role **admin**\n\nCheck if the user session is active","operationId":"os_user_ping_get","x-module":"user","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/user/email":{"post":{"tags":["User"],"summary":"Send an email from the user","description":"`os_user_sendemail_post` · minimal role **teacher**\n\nSend an email from the user","operationId":"os_user_sendemail_post","x-module":"user","x-access":"teacher","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/user/backend/message":{"post":{"tags":["User"],"summary":"Send an email from the user to Omniscol team","description":"`os_user_backend-message_post` · **public**\n\nSend an email from the user to Omniscol team","operationId":"os_user_backend-message_post","x-module":"user","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/login":{"post":{"tags":["Guest"],"summary":"Log in as a guest user","description":"`os_guest_login_post` · **public**\n\nLog in as a guest user","operationId":"os_guest_login_post","x-module":"guest","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/login/{authtoken}":{"post":{"tags":["Guest"],"summary":"Log in as a guest user using an authentication token","description":"`os_guest_loginbyauthtoken_post` · **public**\n\nLog in as a guest user using an authentication token","operationId":"os_guest_loginbyauthtoken_post","x-module":"guest","x-access":"all","parameters":[{"name":"authtoken","in":"path","required":true,"schema":{"type":"string","description":"authentication token"},"description":"authentication token"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/share":{"get":{"tags":["Guest"],"summary":"Retrieve sharing links with embedded authentication for user","description":"`os_guest_share_get` · minimal role **student**\n\nRetrieve sharing links with embedded authentication for user","operationId":"os_guest_share_get","x-module":"guest","x-access":"student","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/keypairs":{"get":{"tags":["Guest"],"summary":"Retrieve the list of API key pairs","description":"`os_guest_keypair_get` · minimal role **admin** · **Premium**\n\nRetrieve the list of API key pairs","operationId":"os_guest_keypair_get","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"post":{"tags":["Guest"],"summary":"Create an API key pair","description":"`os_guest_keypair_post` · minimal role **admin** · **Premium**\n\nCreate an API key pair","operationId":"os_guest_keypair_post","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/keypairs/{id}":{"put":{"tags":["Guest"],"summary":"Update an API key pair","description":"`os_guest_keypair_put` · minimal role **admin** · **Premium**\n\nUpdate an API key pair","operationId":"os_guest_keypair_put","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"key pair ID"},"description":"key pair ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Guest"],"summary":"Delete an API key pair","description":"`os_guest_keypair_delete` · minimal role **admin** · **Premium**\n\nDelete an API key pair","operationId":"os_guest_keypair_delete","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"key pair ID"},"description":"key pair ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/keypairs/{id}/token":{"post":{"tags":["Guest"],"summary":"Generate a JWT token derived from a specific key pair","description":"`os_guest_keypair-token_post` · minimal role **admin**\n\nGenerate a JWT token derived from a specific key pair","operationId":"os_guest_keypair-token_post","x-module":"guest","x-access":"admin","parameters":[{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"key pair ID"},"description":"key pair ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/school-create":{"post":{"tags":["Guest"],"summary":"Create a new school account","description":"`os_guest_school-create_post` · **public**\n\nCreate a new school account","operationId":"os_guest_school-create_post","x-module":"guest","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/password-reset":{"post":{"tags":["Guest"],"summary":"Reset user's password","description":"`os_guest_password-reset_post` · **public**\n\nReset user's password","operationId":"os_guest_password-reset_post","x-module":"guest","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/switch/{schoolid}":{"get":{"tags":["Guest"],"summary":"Switch to a different school (automatic creation)","description":"`os_guest_switch_get` · **public**\n\nSwitch to a different school (automatic creation)","operationId":"os_guest_switch_get","x-module":"guest","x-access":"all","parameters":[{"name":"schoolid","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/password-lost":{"post":{"tags":["Guest"],"summary":"Initiate the password recovery process for a guest user","description":"`os_guest_password-lost_post` · **public**\n\nInitiate the password recovery process for a guest user","operationId":"os_guest_password-lost_post","x-module":"guest","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/invitations":{"post":{"tags":["Guest"],"summary":"Managing invitations to create school accounts","description":"`os_guest_invitations_post` · minimal role **admin**\n\nManaging invitations to create school accounts","operationId":"os_guest_invitations_post","x-module":"guest","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/school":{"get":{"tags":["Guest"],"summary":"Retrieve information about a school, for login page","description":"`os_guest_school_get` · **public**\n\nRetrieve information about a school, for login page","operationId":"os_guest_school_get","x-module":"guest","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/endpoints":{"get":{"tags":["Guest"],"summary":"Retrieve the list of available endpoints","description":"`os_guest_endpoints_get` · **public**\n\nRetrieve the list of available endpoints","operationId":"os_guest_endpoints_get","x-module":"guest","x-access":"all","parameters":[{"name":"modules","in":"query","required":false,"schema":{"type":"array","items":{"type":"string","enum":["guest","user","home","schedules","timetables","absences","admin","external","jobs","backoffice"]},"description":"list of specific modules of which endpoints to retrieve"},"description":"list of specific modules of which endpoints to retrieve"},{"name":"with_config","in":"query","required":false,"schema":{"type":"boolean","description":"agregate school account configuration"},"description":"agregate school account configuration"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/openapi":{"get":{"tags":["Guest"],"summary":"OpenAPI 3.0 Omniscol's API endpoints","description":"`os_guest_openapi_get` · **public**\n\nOpenAPI 3.0 Omniscol's API endpoints","operationId":"os_guest_openapi_get","x-module":"guest","x-access":"all","parameters":[{"name":"yaml","in":"query","required":false,"schema":{"type":"boolean","description":"output in yaml format"},"description":"output in yaml format"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/api":{"get":{"tags":["Guest"],"summary":"Retrieve the API hooks","description":"`os_guest_api_get` · minimal role **admin** · **Premium**\n\nRetrieve the API hooks","operationId":"os_guest_api_get","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"post":{"tags":["Guest"],"summary":"Create an API hook","description":"`os_guest_api_post` · minimal role **admin** · **Premium**\n\nCreate an API hook","operationId":"os_guest_api_post","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/oauth":{"get":{"tags":["Guest"],"summary":"List all OAuth2 clients","description":"`os_guest_oauth_get` · minimal role **admin** · **Premium**\n\nList all OAuth2 clients","operationId":"os_guest_oauth_get","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"post":{"tags":["Guest"],"summary":"Create new OAuth2 client","description":"`os_guest_oauth-client_post` · minimal role **admin** · **Premium**\n\nCreate new OAuth2 client","operationId":"os_guest_oauth-client_post","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"client_name":{"type":"string"},"software_id":{"type":"string"},"redirect_uris":{"type":"array","items":{"type":"string"}},"scopes":{"type":"array","items":{"type":"string"}},"contacts":{"type":"array","items":{"type":"string"}},"client_uri":{"type":"string"},"logo_uri":{"type":"string"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/oauth/{client_id}":{"get":{"tags":["Guest"],"summary":"Get specific OAuth2 client details","description":"`os_guest_oauth-client_get` · minimal role **admin** · **Premium**\n\nGet specific OAuth2 client details","operationId":"os_guest_oauth-client_get","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","description":"OAuth2 client ID"},"description":"OAuth2 client ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"put":{"tags":["Guest"],"summary":"Update OAuth2 client details","description":"`os_guest_oauth-client_put` · minimal role **admin** · **Premium**\n\nUpdate OAuth2 client details","operationId":"os_guest_oauth-client_put","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","description":"OAuth2 client ID"},"description":"OAuth2 client ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"delete":{"tags":["Guest"],"summary":"Permanently delete OAuth2 client","description":"`os_guest_oauth-client_delete` · minimal role **admin** · **Premium**\n\nPermanently delete OAuth2 client","operationId":"os_guest_oauth-client_delete","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","description":"OAuth2 client ID"},"description":"OAuth2 client ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/oauth/{client_id}/activation":{"put":{"tags":["Guest"],"summary":"Set OAuth2 client active status (activate/deactivate)","description":"`os_guest_oauth-client_activation_put` · minimal role **admin** · **Premium**\n\nSet OAuth2 client active status (activate/deactivate)","operationId":"os_guest_oauth-client_activation_put","x-module":"guest","x-premium":true,"x-access":"admin","parameters":[{"name":"client_id","in":"path","required":true,"schema":{"type":"string","description":"OAuth2 client ID"},"description":"OAuth2 client ID"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"active":{"type":"boolean","description":"Whether the client should be active (true) or inactive (false)"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/guest/schools/{schoolid}":{"get":{"tags":["Guest"],"summary":"Test is host name for school account exists","description":"`os_guest_domaintest` · **public**\n\nTest is host name for school account exists","operationId":"os_guest_domaintest","x-access":"all","parameters":[{"name":"schoolid","in":"path","required":true,"schema":{"type":"string","description":"school id to test"},"description":"school id to test"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/oauth/authorize":{"post":{"tags":["Oauth2"],"summary":"OAuth 2.0 Authorize","description":"`os_oauth2_authorize_post` · minimal role **admin**\n\nOAuth 2.0 Authorize","operationId":"os_oauth2_authorize_post","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/oauth/token":{"post":{"tags":["Oauth2"],"summary":"OAuth 2.0 Token","description":"`os_oauth2_token_post` · minimal role **admin**\n\nOAuth 2.0 Token","operationId":"os_oauth2_token_post","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/oidc/userinfo":{"get":{"tags":["Oauth2"],"summary":"OAuth 2.0 OpenID user info","description":"`os_oauth2_userinfo_get` · minimal role **admin**\n\nOAuth 2.0 OpenID user info","operationId":"os_oauth2_userinfo_get","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/auth/oidc/info":{"get":{"tags":["Oidc"],"summary":"Get public OIDC configuration for login page","description":"`os_oidc_info_get` · **public**\n\nGet public OIDC configuration for login page","operationId":"os_oidc_info_get","x-module":"oidc","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/auth/oidc/links":{"get":{"tags":["Oidc"],"summary":"List OIDC providers linked to current user","description":"`os_oidc_links_get` · minimal role **teacher**\n\nList OIDC providers linked to current user","operationId":"os_oidc_links_get","x-module":"oidc","x-access":"teacher","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"post":{"tags":["Oidc"],"summary":"Persist OIDC provider link after successful authentication","description":"`os_oidc_link` · **public**\n\nPersist OIDC provider link after successful authentication","operationId":"os_oidc_link","x-module":"oidc","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/auth/oidc/links/{provider}":{"delete":{"tags":["Oidc"],"summary":"Unlink OIDC provider from current user","description":"`os_oidc_unlink` · minimal role **teacher**\n\nUnlink OIDC provider from current user","operationId":"os_oidc_unlink","x-module":"oidc","x-access":"teacher","parameters":[{"name":"provider","in":"path","required":true,"schema":{"type":"string"}}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/oidc":{"put":{"tags":["Admin"],"summary":"Configure OIDC settings for the school","description":"`os_admin_oidc_put` · minimal role **admin**\n\nConfigure OIDC settings for the school","operationId":"os_admin_oidc_put","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchoolConfigOidc"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}},"get":{"tags":["Admin"],"summary":"Get OIDC configuration for the school (secrets hidden)","description":"`os_admin_oidc_get` · minimal role **admin**\n\nGet OIDC configuration for the school (secrets hidden)","operationId":"os_admin_oidc_get","x-module":"admin","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/admin/oidc/test":{"post":{"tags":["Admin"],"summary":"Test OIDC configuration (admin-only)","description":"`os_admin_oidc_test_post` · minimal role **admin**\n\nTest OIDC configuration (admin-only)","operationId":"os_admin_oidc_test_post","x-module":"admin","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"$ref":"#/components/schemas/SchoolConfigOidc"}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/external/classes":{"post":{"tags":["External"],"summary":"Synchronize classes from another external database","description":"`os_external_classes_post` · minimal role **admin**\n\nSynchronize classes from another external database","operationId":"os_external_classes_post","x-module":"external","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/external/classes/{classid}":{"delete":{"tags":["External"],"summary":"Synchronize class deletion from another external database","description":"`os_external_classes_delete` · minimal role **admin**\n\nSynchronize class deletion from another external database","operationId":"os_external_classes_delete","x-module":"external","x-access":"admin","parameters":[{"name":"classid","in":"path","required":true,"schema":{"type":"string","description":"class ID"},"description":"class ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/external/teachers":{"post":{"tags":["External"],"summary":"Synchronize teachers from another external database","description":"`os_external_teachers_post` · minimal role **admin**\n\nSynchronize teachers from another external database","operationId":"os_external_teachers_post","x-module":"external","x-access":"admin","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/external/teachers/{teacherid}":{"delete":{"tags":["External"],"summary":"Synchronize teacher deletion from another external database","description":"`os_external_teachers_delete` · minimal role **admin**\n\nSynchronize teacher deletion from another external database","operationId":"os_external_teachers_delete","x-module":"external","x-access":"admin","parameters":[{"name":"teacherid","in":"path","required":true,"schema":{"type":"string","description":"teacher ID"},"description":"teacher ID"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"}}}}}}}}},"/api/external/extsync/{system}/{entity}":{"get":{"tags":["External"],"summary":"Fetch data from configured ERP system (Auriga, Aurion, etc.)","description":"`os_external_extsync-entity_get` · minimal role **admin** · **Premium**\n\nFetch data from configured ERP system (Auriga, Aurion, etc.)","operationId":"os_external_extsync-entity_get","x-module":"external","x-premium":true,"x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"enum":["teachers","subjects","classes","classrooms","groups","resources","sites","types","status"],"description":"Entity to fetch from the external ERP system"},"description":"Entity to fetch from the external ERP system"},{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"},{"name":"with_omniscol_entities","in":"query","required":false,"schema":{"type":"boolean","description":"Also return internal Omniscol entities for matching, aggregated from Omniscol data sources (users, subjects_custom, timetables)"},"description":"Also return internal Omniscol entities for matching, aggregated from Omniscol data sources (users, subjects_custom, timetables)"},{"name":"timetable","in":"query","required":false,"schema":{"type":"string","description":"Optional timetable ID used to derive date range tweaks for connectors that support date-scoped entities"},"description":"Optional timetable ID used to derive date range tweaks for connectors that support date-scoped entities"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"system":{"type":"string","description":"Resolved external system key actually used for the request"},"data":{"type":"object","description":"Connector payload keyed by the requested entity name. Some connectors may also return companion collections such as families."},"omniscol_entities":{"type":"object","description":"Omniscol entities keyed by entity type, returned only when with_omniscol_entities=true"}}}}}}}},"put":{"tags":["External"],"summary":"Sync entity data with external ERP system","description":"`os_external_extsync-entity_put` · minimal role **admin** · **Premium**\n\nSync entity data with external ERP system","operationId":"os_external_extsync-entity_put","x-module":"external","x-premium":true,"x-access":"admin","parameters":[{"name":"entity","in":"path","required":true,"schema":{"enum":["teachers","subjects","classrooms","resources","groups","sites","classes"],"description":"Entity type to synchronize into Omniscol"},"description":"Entity type to synchronize into Omniscol"},{"name":"system","in":"path","required":true,"schema":{"description":"External system key (e.g., auriga, aurion, aimaira)"},"description":"External system key (e.g., auriga, aurion, aimaira)"}],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"timetable":{"oneOf":[{"type":"string"},{"type":"array","items":{"type":"string"}}],"description":"Target timetable ID or IDs. Required for timetable-scoped entities such as sites, classes, groups, classrooms and resources."},"site":{"type":"string","description":"Site ID for classroom synchronization (required for classrooms entity)"},"class":{"type":"string","description":"Class ID for group synchronization (required for groups entity)"},"added":{"type":"array","items":{"type":"object"},"description":"Items to add"},"updated":{"type":"array","items":{"type":"object"},"description":"Items to update"},"removed":{"type":"array","items":{"type":"object"},"description":"Items to remove"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"aggregatedResults":{"type":"object","description":"Outcome grouped by added, updated and removed operations. The exact nested shape depends on the delegated Omniscol APIs used for the selected entity."}}}}}}}}},"/api/external/export/lessons":{"post":{"tags":["External"],"summary":"Export lessons to configured ERP system(s)","description":"`os_external_export-lessons_post` · minimal role **admin** · **Premium**\n\nExport lessons to configured ERP system(s)","operationId":"os_external_export-lessons_post","x-module":"external","x-premium":true,"x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"system":{"type":"string","description":"Target system slug (auriga, aimaira, etc.). If not specified, exports to all enabled systems."},"exclude_unpositioned":{"type":"boolean","description":"Full export only. When true, excludes unpositioned lessons (lessons without date/time) from published calendar timetables. Default: false (include them)."},"diff":{"type":"object","description":"Optional diff payload for realtime export (added/updated/removed)"}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Immediate launch status, typically export_started in normal mode"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"system":{"type":"string","description":"Target system key, or all when all enabled systems are targeted"},"exportResult":{"type":"object","description":"Detailed export result returned only in TEST_MODE"}}}}}}}},"get":{"tags":["External"],"summary":"Fetch lessons from configured ERP system (for visualization)","description":"`os_external_export-lessons_get` · minimal role **admin** · **Premium**\n\nFetch lessons from configured ERP system (for visualization)","operationId":"os_external_export-lessons_get","x-module":"external","x-premium":true,"x-access":"admin","parameters":[{"name":"system","in":"query","required":false,"schema":{"type":"string","description":"Target system slug (auriga, etc.). Required."},"description":"Target system slug (auriga, etc.). Required."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"data":{"type":"array","items":{"type":"object"},"description":"Lessons returned by the ERP connector for the selected system"}}}}}}}},"delete":{"tags":["External"],"summary":"Purge Omniscol-exported interventions from configured ERP system (dangerous)","description":"`os_external_export-lessons_delete` · minimal role **superadmin** · **Premium**\n\nPurge Omniscol-exported interventions from configured ERP system (dangerous)","operationId":"os_external_export-lessons_delete","x-module":"external","x-premium":true,"x-access":"superadmin","parameters":[{"name":"system","in":"query","required":false,"schema":{"type":"string","description":"Target system slug (auriga, etc.). Required."},"description":"Target system slug (auriga, etc.). Required."}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Immediate purge status, typically purge_started in normal mode"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"system":{"type":"string","description":"Target system key"},"purgeResult":{"type":"object","description":"Detailed purge result returned only in TEST_MODE"}}}}}}}}},"/api/help/bundle/{lang}":{"get":{"tags":["Help"],"summary":"Full help corpus for one language: navigation index plus every page. ETag-cached","description":"`os_help_bundle_get` · **public**\n\nFull help corpus for one language: navigation index plus every page. ETag-cached","operationId":"os_help_bundle_get","x-access":"all","parameters":[{"name":"lang","in":"path","required":true,"schema":{"type":"string","description":"Language code (e.g. fr, en, zh-cn)"},"description":"Language code (e.g. fr, en, zh-cn)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"lang":{"type":"string","description":"Served language code"},"tree":{"type":"object","description":"Nav pages grouped by parent (see the index endpoint)","additionalProperties":true},"routeToPage":{"type":"object","additionalProperties":true},"i18nToPage":{"type":"object","additionalProperties":true},"glossaryToPage":{"type":"object","additionalProperties":true},"search":{"type":"object","description":"In-browser search subset","additionalProperties":true},"pages":{"type":"object","description":"Every page keyed by id (same shape as the page endpoint)","additionalProperties":true},"tours":{"type":"object","description":"Every guided tour keyed by id","additionalProperties":true},"dataElementGlossary":{"type":"object","additionalProperties":true},"routeToTour":{"type":"object","additionalProperties":true},"videoTours":{"type":"object","additionalProperties":true},"tableOfContents":{"type":"object","additionalProperties":true},"dataElements":{"type":"object","additionalProperties":true},"legendEntries":{"type":"object","additionalProperties":true}}}}}}}}},"/api/help/index/{lang}":{"get":{"tags":["Help"],"summary":"Help navigation index for one language: sections and page list, without page bodies","description":"`os_help_index_get` · **public**\n\nHelp navigation index for one language: sections and page list, without page bodies","operationId":"os_help_index_get","x-access":"all","parameters":[{"name":"lang","in":"path","required":true,"schema":{"type":"string","description":"Language code (e.g. fr, en, zh-cn)"},"description":"Language code (e.g. fr, en, zh-cn)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"lang":{"type":"string","description":"Served language code"},"tree":{"type":"object","description":"Pages grouped by parent; pseudo-parent __root__ holds top-level pages","additionalProperties":{"type":"array","items":{"type":"object","properties":{"id":{"type":"string"},"title":{"type":"string"},"slug":{"type":"string"},"order":{"type":"number"},"audience":{"type":"array","items":{"type":"string"}},"license":{"type":["string","null"]},"feature":{"type":["string","null"]},"country":{"type":["string","null"]}}}}},"routeToPage":{"type":"object","description":"SPA route pattern to page ids","additionalProperties":{"type":"array","items":{"type":"string"}}},"i18nToPage":{"type":"object","description":"i18n key to page ids","additionalProperties":{"type":"array","items":{"type":"string"}}},"glossaryToPage":{"type":"object","description":"Glossary term to page ids","additionalProperties":{"type":"array","items":{"type":"string"}}},"search":{"type":"object","description":"In-browser full-text search subset","properties":{"docs":{"type":"array","items":{"type":"object","additionalProperties":true}},"inverted":{"type":"object","additionalProperties":{"type":"array","items":{"type":"object","properties":{"doc":{"type":"number"},"freq":{"type":"number"}}}}}}}}}}}}}}},"/api/help/page/{lang}/{id}":{"get":{"tags":["Help"],"summary":"A single help page: metadata, content and table of contents","description":"`os_help_page_get` · **public**\n\nA single help page: metadata, content and table of contents","operationId":"os_help_page_get","x-access":"all","parameters":[{"name":"lang","in":"path","required":true,"schema":{"type":"string","description":"Language code"},"description":"Language code"},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Page id in dot notation (e.g. absences.overview)"},"description":"Page id in dot notation (e.g. absences.overview)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"id":{"type":"string"},"lang":{"type":"string"},"path":{"type":"string","description":"On-disk slashed path"},"slug":{"type":"string"},"title":{"type":"string"},"parent":{"type":"string"},"audience":{"type":"array","items":{"type":"string"}},"license":{"type":["string","null"]},"feature":{"type":["string","null"]},"country":{"type":["string","null"]},"order":{"type":"number"},"related":{"type":"array","items":{"type":"string"}},"glossary_terms":{"type":"array","items":{"type":"string"}},"tags":{"type":"array","items":{"type":"string"}},"context":{"type":"object","properties":{"routes":{"type":"array","items":{"type":"string"}},"i18n_keys":{"type":"array","items":{"type":"string"}}}},"toc":{"type":"array","items":{"type":"object","properties":{"level":{"type":"number"},"text":{"type":"string"},"anchor":{"type":"string"}}}},"ast":{"type":"array","description":"Rendered Markdown AST (mdast) with interleaved helpsystem directive nodes","items":{"type":"object","properties":{"type":{"type":"string"}},"additionalProperties":true}}}}}}}}}},"/api/help/search/{lang}":{"get":{"tags":["Help"],"summary":"Full-text search index for the help corpus in one language","description":"`os_help_search_get` · **public**\n\nFull-text search index for the help corpus in one language","operationId":"os_help_search_get","x-access":"all","parameters":[{"name":"lang","in":"path","required":true,"schema":{"type":"string","description":"Language code"},"description":"Language code"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"lang":{"type":"string","description":"Served language code"},"docs":{"type":"array","description":"Searchable documents; inverted hits point here via doc index","items":{"type":"object","properties":{"id":{"type":"string"},"slug":{"type":"string"},"title":{"type":"string"},"parent":{"type":"string"},"audience":{"type":"array","items":{"type":"string"}}}}},"inverted":{"type":"object","description":"Token to document-hit list (lowercased, stopwords removed)","additionalProperties":{"type":"array","items":{"type":"object","properties":{"doc":{"type":"number"},"freq":{"type":"number"}}}}}}}}}}}}},"/api/help/tour/{lang}/{id}":{"get":{"tags":["Help"],"summary":"Guided-tour definition for one tour: ordered steps and actions","description":"`os_help_tour_get` · **public**\n\nGuided-tour definition for one tour: ordered steps and actions","operationId":"os_help_tour_get","x-access":"all","parameters":[{"name":"lang","in":"path","required":true,"schema":{"type":"string","description":"Language code"},"description":"Language code"},{"name":"id","in":"path","required":true,"schema":{"type":"string","description":"Tour id (e.g. schedules.first-tour)"},"description":"Tour id (e.g. schedules.first-tour)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"id":{"type":"string"},"title":{"type":"string"},"lang":{"type":"string"},"page":{"type":["string","null"],"description":"Help page the tour is anchored to"},"routes":{"type":"array","items":{"type":"string"},"description":"SPA routes the tour runs on"},"next":{"type":["string","null"],"description":"Id of the tour suggested next"},"record":{"type":"boolean","description":"Whether the tour is part of the video-recording set"},"triggers_legend":{"type":"boolean","description":"Whether the tour opens the legend overlay"},"steps":{"type":"array","items":{"type":"object","properties":{"ui":{"type":["string","null"],"description":"data-element to highlight for this step"},"advance":{"type":"string","description":"Progression mode: click | next | auto:Nms"},"route":{"type":["string","null"]},"position":{"type":"string","description":"Popover placement (e.g. auto)"},"setup":{"type":["string","null"]},"teardown":{"type":["string","null"]},"skip":{"type":"boolean"},"body":{"type":"array","description":"mdast AST for the step body","items":{"type":"object","properties":{"type":{"type":"string"}},"additionalProperties":true}}}}}}}}}}}}},"/api/help/operation/{operationId}":{"get":{"tags":["Help"],"summary":"Documentation metadata for one API operation (minimal role, Premium, module)","description":"`os_help_operation_get` · **public**\n\nDocumentation metadata for one API operation (minimal role, Premium, module)","operationId":"os_help_operation_get","x-access":"all","parameters":[{"name":"operationId","in":"path","required":true,"schema":{"type":"string","description":"Operation id (e.g. os_absences_classes_get)"},"description":"Operation id (e.g. os_absences_classes_get)"}],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"operationId":{"type":"string"},"httpMethod":{"type":"array","items":{"type":"string"}},"urls":{"type":"array","items":{"type":"string"},"description":"Route patterns serving this operation"},"access":{"type":"array","items":{"type":"string"},"description":"Roles accepted (minimal required role)"},"premium":{"type":"boolean","description":"Whether the operation is Premium-gated"},"mcp_exposed":{"type":"boolean","description":"Whether the operation is exposed as an MCP tool"},"type":{"type":"string","description":"Account type gate (e.g. premium)"},"module_depends":{"type":"string","description":"Module the operation depends on"},"type_excludes":{"type":"string","description":"Account type that excludes the operation"},"condition":{"type":"string","description":"Config condition gating the operation (e.g. config.customroles)"},"declination_of":{"type":"string","description":"Canonical operation this one is a variant of"}}}}}}}}},"/api/help/chat":{"post":{"tags":["Help"],"summary":"Conversational help agent answering questions over the help corpus","description":"`os_help_chat_post` · minimal role **admin**\n\nConversational help agent answering questions over the help corpus","operationId":"os_help_chat_post","x-access":"admin","parameters":[],"requestBody":{"required":true,"content":{"application/json":{"schema":{"type":"object","properties":{"message":{"type":"string","description":"User question (max 2000 chars); omitted only for resume/compact payloads"},"lang":{"type":"string","description":"Answer language (e.g. fr, en, zh-cn); defaults to fr"},"history":{"type":"array","description":"Prior turns (rolling summary plus recent messages)","items":{"type":"object","properties":{"role":{"type":"string","enum":["user","assistant"]},"text":{"type":"string"}}}},"images":{"type":"array","description":"Optional attached images","items":{"type":"object","additionalProperties":true}},"context":{"type":"string","description":"Ambient SPA context passed verbatim (max 4000 chars)"},"resume":{"type":"object","description":"Write-confirmation payload resuming a pending agent action","additionalProperties":true},"approvals":{"type":"object","description":"Per-action approval map accompanying a resume","additionalProperties":true},"compact":{"type":"object","description":"History-summarization payload (carries no message)","additionalProperties":true},"contact_draft":{"type":"object","description":"Contact-message draft payload (compose a ready-to-send message from the chat history; carries no message field)","additionalProperties":true}}}}}},"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":["string","null"],"description":"Returned by the contact_draft path — the composed contact-form message"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"status":{"type":"string","description":"ok | no_answer | refused | no_match | rate_limited | not_configured | unavailable | error"},"profile":{"type":"string","description":"Answer profile used (premium agent vs cheap public)"},"reply":{"type":["string","null"],"description":"Grounded answer text (null when no answer)"},"sources":{"type":"array","description":"Cited help pages","items":{"type":"object","additionalProperties":true}},"ui_actions":{"type":"array","description":"Suggested SPA actions (navigate / highlight)","items":{"type":"object","additionalProperties":true}},"tools_used":{"type":"array","items":{"type":"string"}},"pending":{"type":"array","description":"Actions awaiting user confirmation","items":{"type":"object","additionalProperties":true}},"resume":{"type":["object","null"],"description":"Opaque token to resume after confirmation","additionalProperties":true},"retry_after":{"type":["number","null"],"description":"Seconds to wait, on rate_limited"},"usage":{"type":["object","null"],"description":"Token usage for the turn","additionalProperties":true},"summary":{"type":"object","description":"Returned by the compact (history-summarization) path","additionalProperties":true}}}}}}}}},"/api/help/availability":{"get":{"tags":["Help"],"summary":"Whether the conversational help agent is currently available for this account","description":"`os_help_availability_get` · **public**\n\nWhether the conversational help agent is currently available for this account","operationId":"os_help_availability_get","x-access":"all","parameters":[],"responses":{"200":{"description":"Successful response","content":{"application/json":{"schema":{"type":"object","properties":{"success":{"type":"boolean","description":"Request success state"},"message":{"type":"string","description":"Error message when success is false"},"reqtime":{"type":"number","description":"Time to make the request, in ms"},"available":{"type":"boolean","description":"Whether the agent is currently usable for this account"},"provider":{"type":["string","null"],"description":"Active answer provider (claude | cf) or null"},"reason":{"type":["string","null"],"description":"Why unavailable (cap reached, not configured, ...)"}}}}}}}}}},"components":{"securitySchemes":{"bearerAuth":{"type":"http","scheme":"bearer","bearerFormat":"JWT","description":"JWT in the `Authorization: Bearer <token>` header."},"cookieAuth":{"type":"apiKey","in":"cookie","name":"authtoken","description":"JWT in the `authtoken` cookie."},"queryAuth":{"type":"apiKey","in":"query","name":"auth","description":"JWT in the `?auth=<token>` query parameter (read-only / show routes)."}},"schemas":{"SchoolYear":{"type":"object","properties":{"name":{"description":"Name of the school year","type":"string"},"date_start":{"description":"Start date","type":"string","format":"date"},"date_end":{"description":"End date","type":"string","format":"date"},"holidays":{"description":"Holidays","type":"array","items":{"$ref":"#/components/schemas/Holiday"}},"altweeks":{"description":"Array of alternate weeks to determine wether to change the alterations at some point, mainly because of holidays","type":"array","items":{"type":"integer"}}},"required":["name","date_start","date_end"]},"Holiday":{"type":"object","properties":{"name":{"type":"string"},"begin":{"type":"string","format":"date"},"end":{"type":"string","format":"date"}},"required":["name","begin","end"]},"UserMinimal":{"description":"User minimal fields","type":"object","properties":{"first_name":{"description":"Fist name","type":"string"},"middle_name":{"description":"Middle name (if support activated)","type":"string"},"last_name":{"description":"Last name","type":"string"},"gender":{"description":"Gender (Male, Female, Unknown)","type":"string","enum":["M","F","U"]},"birthdate":{"description":"Birthdate (YYYY-MM-DD)","type":"string","format":"date"},"email":{"description":"E-mail","type":"string","format":"email"},"phone":{"description":"Phone number","type":"string"},"idnumber":{"description":"ID number (e.g. defined by the Ministry of Education, or the school)","type":"string"},"comment":{"description":"Free comment","type":"string"}}},"Placement":{"type":"object","properties":{"class":{"description":"Class assigned to the student","type":"string"},"date_start":{"description":"Start date (if absent = start of the school year) (YYYY-MM-DD)","type":"string","format":"date"},"date_end":{"description":"End date (if absent = end of the school year) (YYYY-MM-DD)","type":"string","format":"date"},"groups":{"description":"Groups assigned to the student","type":"array","items":{"$ref":"#/components/schemas/PlacementGroup"}}},"required":["class"]},"PlacementGroup":{"type":"object","properties":{"group":{"description":"Group ID. Can be a regular group ID, a named groupset ID, or a virtual multigroup ID using CSV notation (for example c1:g1,c2:g2).","type":"string"},"weeks":{"description":"Array of week ranges [start, end] or single week numbers","type":"array","items":{"oneOf":[{"type":"number"},{"type":"array","items":{"type":"number"},"minItems":2,"maxItems":2}]}}}},"TeacherMinimal":{"description":"Teacher minimal fields","allOf":[{"$ref":"#/components/schemas/UserMinimal"},{"type":"object","properties":{"wishes":{"allOf":[{"$ref":"#/components/schemas/WishesTeachers"},{"description":"Teacher's wishes/availabilities"}]},"external":{"description":"External teacher flag (only stored if true)","type":"boolean","x-premiumOnly":true}}}]},"WishesTeachers":{"allOf":[{"$ref":"#/components/schemas/Wishes"},{"type":"object","properties":{"priority":{"description":"What is the priority of this wish compared to other wishes (low, normal or high)","type":"string","enum":["low","normal","high"],"default":"normal"},"consecutivedaysmin":{"description":"Number of minimum consecutive days with lessons","type":"number"},"consecutivedaysmax":{"description":"Number of maximum consecutive days with lessons","type":"number"}}}]},"Wishes":{"type":"object","properties":{"hours":{"description":"Specific rules on hours for availabilities","type":"array","items":{"description":"Time span with associated rule for availability/wish/preference","type":"object","properties":{"day":{"description":"Day, date or cycle day. If no time bound is provided, the wish applies to the whole day.","type":"string","oneOf":[{"format":"date","type":"string"},{"enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"type":"string"},{"pattern":"^[0-9]+$","type":"string"}]},"school_year":{"description":"Optional school year scope for recurring non-dated wishes in calendar mode.","type":"string"},"period_begin":{"description":"Start in period number (exclusive to minute bounds). If omitted while period_end is present, the span starts at the beginning of the day.","type":"integer"},"period_end":{"description":"End in period number (exclusive to minute bounds). This bound is *excluded*, meaning the span is [period_begin, period_end[. If omitted while period_begin is present, the span ends at the end of the day.","type":"integer"},"begin":{"description":"Start in minutes (exclusive to period bounds). If omitted while end is present, the span starts at the beginning of the day.","type":"integer"},"end":{"description":"End in minutes (exclusive to period bounds). If omitted while begin is present, the span ends at the end of the day.","type":"integer"},"priority":{"description":"Priority associated to the rule. \"mandatory\" is *strong* (must ABSOLUTELY be avoided), \"high\" may be strongly avoided if possible, \"medium\" is not preferred, \"preferred\" is positive preference, and \"none\" explicitly erases the effect of previous wishes on the covered span. \"custom\" is a frontend-only intermediate state and is not persisted in Wishes storage.","type":"string","enum":["mandatory","high","medium","preferred","none"]},"sites":{"description":"Optional sites the wishes are referring to","type":"array","items":{"type":"string"}}},"required":["day","priority"],"oneOf":[{"properties":{"period_begin":{"not":{}},"period_end":{"not":{}},"begin":{"not":{}},"end":{"not":{}}},"type":"object"},{"anyOf":[{"required":["period_begin"],"type":"object"},{"required":["period_end"],"type":"object"}],"properties":{"begin":{"not":{}},"end":{"not":{}}},"type":"object"},{"anyOf":[{"required":["begin"],"type":"object"},{"required":["end"],"type":"object"}],"properties":{"period_begin":{"not":{}},"period_end":{"not":{}}},"type":"object"}]}},"time_unit":{"description":"If it is in period number, what is the time unit as in the grid","type":"number","default":1},"time_period":{"description":"If it is in period number, what is the time period as in the grid","type":"number","default":60},"maxhours":{"description":"Maximum number of lesson hours per day (format \"HH:MM\" preferred, integer hours accepted)","allOf":[{"$ref":"#/components/schemas/DurationHHMMOrHours"}]},"maxhoursweek":{"description":"Maximum number of lesson hours per week (format \"HH:MM\" preferred, integer hours accepted)","allOf":[{"$ref":"#/components/schemas/DurationHHMMOrHours"}]},"comment":{"description":"Free comment, for example to be used by teachers to communicate specific remarks on their wishes","type":"string"},"date_windows":{"description":"Optional array of date window IDs (slugs) to constrain when lessons can be scheduled. Only valid for calendar timetables","type":"array","items":{"type":"string"}}}},"DurationHHMMOrHours":{"description":"Duration as \"HH:MM\" (preferred) or integer number of hours","oneOf":[{"type":"string","pattern":"^[0-9]{1,3}:[0-5][0-9]$"},{"type":"integer","minimum":0}],"examples":[]},"Timetable":{"description":"A timetable represents a coherent scheduling unit within the software. It defines the set of classes that have lessons over a specific period of time, such as a school year, a semester, or a trimester. The period must be homogeneous and logically consistent. In premium mode, multiple timetables can coexist in parallel — for example, one for middle school and another for high school — each functioning as an independent and self-contained scheduling entity.","type":"object","properties":{"config":{"$ref":"#/components/schemas/TimetableConfig"},"sites":{"description":"Sites (campuses)","type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableSite"}},"teachers":{"description":"Teachers assigned to the timetable, by ID (should be the same as in users)","type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableTeacher"}},"classes":{"title":"Classes","description":"A class is a stable set of students having lessons mostly together, who share the same timetable, except when they are seperated in different groups (as subsets). In the US, it is similar to a homeroom, grade level or cohort. In the UK, that would be a year group or a form. In higher education, that could be a cohort.","type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClass"}},"lessons":{"description":"Lessons common to different classes because of groups of groups","type":"array","items":{"$ref":"#/components/schemas/Lesson"}},"groups":{"description":"Rules between groups","type":"object","properties":{"timeset":{"$ref":"#/components/schemas/TimetableGroupTimeset"},"spaceset":{"$ref":"#/components/schemas/TimetableGroupSpaceset"},"groupset":{"$ref":"#/components/schemas/TimetableGroupGroupset"}}},"activation":{"description":"When the weekly or cycle timetable should be published/active (boolean true = published for all weeks)","type":["array","boolean"],"items":{"description":"Start/end in weeks (since EPOCH)","type":"array","items":{"type":"integer"}}},"active":{"description":"Is this timetable activated/published?","type":"boolean"},"date_generation":{"allOf":[{"$ref":"#/components/schemas/CustomDateTimeFormat"},{"description":"Timestamp when this timetable was generated. Canonical storage is ISO 8601 UTC (for example 2026-03-03T14:52:19.123Z); legacy values are accepted for backward compatibility."}]},"date_creation":{"allOf":[{"$ref":"#/components/schemas/CustomDateTimeFormat"},{"description":"Timestamp when this timetable was created. Canonical storage is ISO 8601 UTC (for example 2026-03-03T14:52:19.123Z); legacy values are accepted for backward compatibility."}]},"date_update":{"allOf":[{"$ref":"#/components/schemas/CustomDateTimeFormat"},{"description":"Timestamp when this timetable was last updated. Canonical storage is ISO 8601 UTC (for example 2026-03-03T14:52:19.123Z); legacy values are accepted for backward compatibility."}]}}},"TimetableConfig":{"description":"Configuration of the timetable","type":"object","properties":{"label":{"description":"Label","type":"string"},"description":{"description":"Description","type":"string"},"time_period":{"description":"Time slot duration (most of the time 60 = 1 hour)","type":"integer","default":60},"time_unit":{"description":"Division of the time slot (e.g. 2 with a time_period of 60 enables lessons of 1h30","type":"integer","default":1},"colors":{"description":"Colors of the different entities","type":"object","properties":{"classes":{"description":"Colors of classes","type":"object","additionalProperties":{"type":"string"}},"subjects":{"description":"Colors of subjects","type":"object","additionalProperties":{"type":"string"}}}},"weekdays":{"description":"Days of the week (open days with lessons)","type":"array","items":{"type":"string","enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"examples":[["monday","tuesday","wednesday","thursday","friday"],["sunday","monday","tuesday","wednesday","thursday"]]}},"displaymode":{"description":"Defines how the timetable grid is structured in the calendar view. \"hours\": real start/end times (e.g. 09:15–10:10), \"periods\": numbered slots (e.g. 0, 1, 2...), \"agenda\": fixed hourly layout (e.g. 8:00, 9:00, 10:00...), like in calendar apps","type":"string","enum":["hours","periods","agenda"],"default":"hours"},"type":{"description":"Type of timetable. \"Week\": weekly schedule repeated over time. \"cycle\": multi-day cycle (e.g. 6-day rotating schedule), \"calendar\": individual dates are scheduled explicitly, with no repeating pattern","type":"string","enum":["week","cycle","calendar"],"default":"week"},"cycle":{"description":"Number of the multi-day cycle (if type = cycle)","type":"integer"},"dates":{"description":"Start/end dates (if type = calendar)","type":"array","items":{"type":"string","format":"date"},"minItems":2,"maxItems":2,"examples":[]},"date_windows":{"description":"Date windows (time constraints for timetable generation). Only valid when type is 'calendar'","type":"object","additionalProperties":{"$ref":"#/components/schemas/DateWindow"},"x-dependsOn":{"type":"calendar"}},"tweaks":{"$ref":"#/components/schemas/TimetableGenerationTweaks"}}},"DateWindow":{"description":"Date window for timetable generation constraints","type":"object","required":["label","type","intervals"],"properties":{"label":{"description":"Label of the date window","type":"string"},"comment":{"description":"Optional comment","type":"string"},"type":{"description":"Type of constraint: allow (lessons can only be placed in these intervals) or exclude (lessons cannot be placed in these intervals)","type":"string","enum":["allow","exclude"]},"intervals":{"description":"List of date intervals","type":"array","items":{"$ref":"#/components/schemas/DateWindowInterval"}}}},"DateWindowInterval":{"description":"Date interval (from/to dates in ISO format)","type":"object","required":["from","to"],"properties":{"from":{"description":"Start date (ISO format YYYY-MM-DD)","type":"string","format":"date"},"to":{"description":"End date (ISO format YYYY-MM-DD)","type":"string","format":"date"}}},"TimetableGenerationTweaks":{"description":"Tweaks for the generation algorithm","type":"object","properties":{"classes":{"description":"Tweaks for classes/students","type":"object","properties":{"gaps":{"description":"How do the algorithm shoud reduce gaps for students?","type":"string","enum":["high","medium","none"],"default":"high"},"packeddays":{"description":"Preference for packing lessons into fewer days. \"none\": no packing, \"earliest\": pack on earliest days, \"latest\": pack on latest days, \"whatever\": allow packing without preference.","type":"string","enum":["none","earliest","latest","whatever"],"default":"none"},"selfincompatibility":{"description":"Is each subject incompatible with itself during the day (trying to prevent more than 1 subject for each student on the same day)","type":"boolean","default":true},"equaldistribution":{"description":"Trying to balance the number of lessons for each day","type":"boolean","default":true},"minhours":{"description":"Minimum number of lesson hours per day for a class","type":"integer","default":0},"maxhours":{"description":"Maximum number of lesson hours the algorithm should not exceed (0 = deactivated, format \"HH:MM\" preferred)","allOf":[{"$ref":"#/components/schemas/DurationHHMMOrHours"}],"default":0},"maxhoursweek":{"description":"Maximum number of lesson hours in a week the algorithm should not exceed (0 = deactivated, format \"HH:MM\" preferred)","allOf":[{"$ref":"#/components/schemas/DurationHHMMOrHours"}],"default":0}}},"teachers":{"description":"Tweaks for teachers","type":"object","properties":{"days":{"description":"Preference regarding the number of working days per teacher. \"less\": group lessons on fewer days, \"more\": spread lessons over more days, \"whatever\": no preference.","type":"string","enum":["more","whatever","less"],"default":"less"},"equaldistribution":{"description":"If true, tries to distribute lessons evenly across the teacher's working days (best effort)","type":"boolean","default":true},"minhours":{"description":"Minimum number of lesson hours per day for a teacher","type":"integer","default":2},"maxhours":{"description":"Maximum number of lesson hours per day for a teacher (0 = deactivated)","type":"integer","default":0},"gaps":{"description":"Preference for minimizing gaps (idle periods) between lessons during the day. \"high\": strongly avoid gaps, \"medium\": moderate tolerance, \"none\": gaps are acceptable","type":"string","enum":["high","medium","none"],"default":"high"}}}}},"TimetableSite":{"description":"Site (campus)","type":"object","properties":{"name":{"description":"Name of the site","type":"string"},"distances":{"description":"Distances between sites","type":"object","additionalProperties":{"description":"Number of minutes between the site and this one (ID)","type":"integer"}},"hours":{"$ref":"#/components/schemas/TimetableSiteHours"},"classrooms":{"description":"Classrooms","type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClassroom"}},"resources":{"description":"Resources represent physical hardware or materials (such as projectors, laptops, or tablets) that are limited in quantity and allocated to lessons. The available count decreases as these resources are assigned.","type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableResource"}},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}},"TimetableSiteHours":{"description":"Definition of the different slots","type":"object","properties":{"courses":{"description":"Time slots for lessons","type":"object","additionalProperties":{"type":"object","properties":{"from":{"description":"General start hour of all days/the grid","type":"string"},"to":{"description":"General end hour of all days/the grid","type":"string"}},"required":["from","to"]}},"periods":{"description":"Time slots, aka periods","type":"array","items":{"type":"object","properties":{"begin":{"description":"General start hour of the slot","type":["string","number"]},"end":{"description":"General end hour of the slot","type":["string","number"]},"label":{"description":"Label of the slot","type":"string"}},"required":["begin","end"]}},"breaks":{"description":"Breaks during day","type":"array","items":{"description":"Break object","type":"object","properties":{"name":{"description":"Name of the break","type":"string"},"time":{"description":"Start time of the break","type":"string","pattern":"^\\d{2}:\\d{2}$"},"duration":{"description":"Duration of the break","type":"integer"}},"required":["name","time","duration"]}},"lunch":{"description":"Lunch break","type":"object","properties":{"from":{"description":"Start of the lunch break","type":"string"},"to":{"description":"End of the lunch break","type":"string"},"duration":{"description":"Duration of the lunch break, must be lower of equal than end - start. If lower, allows to put lessons on this break, as long as the duration is respected. If lunch starts at 12:00 and ends at 14:00, a duration of 60 allows 1 lesson of an hour to be put at 12:00 or 13:00.","type":"integer"},"pre":{"description":"Is the canteen opened just before the official lunch break, so that a gap on this slot does not count?","type":"boolean"}}},"wishes":{"$ref":"#/components/schemas/Wishes"}}},"TimetableClassroom":{"description":"Classroom","type":"object","properties":{"name":{"description":"Name of the classroom","type":"string"},"capacity":{"description":"Capacity of the classroom (number of seats)","type":"integer"},"specialisation":{"description":"Specialisation of the classroom (free label). To be associated with specific subjects (e.g. stadium with PE)","type":"string"},"maxclasses":{"description":"Maximal number of simultaneous classes having different lessons at the same time. For example, an examination room, or a gymnasium.","type":"integer"},"building":{"description":"Building of the classroom (can also be used to specify the floor)","type":"string"},"wishes":{"allOf":[{"$ref":"#/components/schemas/Wishes"},{"description":"Specific slots when the classroom is available"}]},"description":{"description":"Description of the room","type":"string"},"tags":{"description":"Different tags","type":"array","items":{"type":"string"}},"_extids":{"$ref":"#/components/schemas/ExternalIds"}},"required":["name","capacity"]},"ExternalIds":{"description":"External system identifiers mapping (e.g., {auriga: '12345', aimaira: '67890'})","type":"object","additionalProperties":{"anyOf":[{"type":"string"},{"type":"null"}]}},"TimetableResource":{"description":"Resource","type":"object","properties":{"name":{"description":"Name of the resource","type":"string"},"number":{"description":"How many of this resource","type":"integer"},"_extids":{"$ref":"#/components/schemas/ExternalIds"}},"required":["name","number"]},"TimetableTeacher":{"description":"Teacher assigned to the timetable. Either this is a partial enriched copy of a user with teacher role, either a virtual teacher (a generic one not yet with flesh)","type":"object","properties":{"first_name":{"description":"First name","type":"string"},"middle_name":{"description":"Middle name","type":"string"},"last_name":{"description":"Last name","type":"string"},"gender":{"description":"Gender (Male, Female, Unknown)","type":"string","enum":["M","F","U"]},"virtual_name":{"description":"Virtual teacher name representing a generic role for a teacher not yet hired, e.g., \"math teacher\".","type":"string"},"subjects":{"description":"Subjects taught by the virtual teacher","type":"array","items":{"description":"Subject ID","type":"string"}},"idnumber":{"description":"Teacher's identifier","type":"string"},"servicehours":{"description":"Service hours, i.e. the number of hours the teacher should give on this timetable","type":"integer"},"classroom":{"description":"Preferred room for the teacher (format <siteid>:<classroomid>)","type":"string"},"wishes":{"allOf":[{"$ref":"#/components/schemas/WishesTeachers"},{"description":"Wishes/preferences/availabilities of the teacher"}]},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}},"TimetableClass":{"description":"Class object","allOf":[{"$ref":"#/components/schemas/TimetableClassBase"},{"type":"object","properties":{"students":{"description":"Explicit list of students, only if \"studentsonclasses\" option is set","type":"array","items":{"type":"string"}},"wishes":{"allOf":[{"$ref":"#/components/schemas/Wishes"},{"description":"Time preferences for this class"}]},"subjects":{"description":"Subjects being taught to the class. Note: The subject id may include an optional ~<typeslug> suffix (e.g. custom123~tp); the base id is the part before ~.","type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableClassSubject"}},"groups":{"$ref":"#/components/schemas/TimetableClassGroups"},"courses":{"description":"List of the lessons of the class","type":"array","items":{"$ref":"#/components/schemas/LessonClass"}}}}],"required":["name"]},"TimetableClassBase":{"description":"Base class for all timetable classes","type":"object","properties":{"name":{"description":"Name of the class","type":"string"},"level":{"description":"Level of the class","type":"string"},"campus":{"description":"Campus label of the class","type":"string","x-premiumOnly":true},"site":{"description":"Default site of the class. Prefer \"sites\" key","type":"string"},"sites":{"description":"Default sites of the class. As for now, used only with first element","type":"array","items":{"type":"string"}},"offgrid":{"description":"On a calendar-type timetable, lessons of this class are scheduled outside the standard timetable grid, using start/end as the source of truth","type":"boolean","x-premiumOnly":true},"time_unit":{"description":"Subdivision count of one hour for off-grid classes (for example 4 exposes 15-minute slots)","type":"integer","minimum":1,"x-premiumOnly":true},"classroom":{"description":"Default classroom for the class (format <siteid>:<classroomid>). If several classrooms are set, they are separated by commas","type":"string"},"studentsnb":{"description":"Number of students of the class","type":"integer"},"videolink":{"description":"Video link to be set on every lessons on grid, by default (can be overloaded by a specific videolink on lesson)","type":"string","x-premiumOnly":true},"resourcelink":{"description":"Resource link to be set on every lessons on grid, by default (such as a LMS space for the class)","type":"string","x-premiumOnly":true},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}},"TimetableClassSubject":{"description":"A subject object as a local copy either from the common subjects of a country, or a specific custom subject (local to the school)","allOf":[{"$ref":"#/components/schemas/Subject"},{"type":"object","properties":{"incompatibilities":{"description":"Rules of incompatibilities between the subject and the other ones","type":"array","items":{"description":"Rule of incompatibility","type":"object","properties":{"notbefore":{"description":"This subject should not be put before this other subject","type":"string"},"type":{"description":"Type of the rule, as the time span to consider its effects","type":"string","enum":["consecutive","halfday","day","week","always"]}},"required":["notbefore","type"]}},"pweight":{"description":"Pedagogical weight. Useful for the algorithm to balance days with subject difficulties","type":"number","default":1},"teachers":{"description":"Teachers by default teaching this subject","type":"array","items":{"type":"string"}},"minutes":{"description":"Number of minutes to teach on the timetable (from the student point of view). If a subject is 3 hours every 2 weeks, put 90. If group A has 4 hours and group B also, put 240","type":"number"},"specialisation":{"description":"Optional specialisation of the needed classroom, must match at least one classroom with the exact same \"specialisation\" field","type":"string"},"wishes":{"allOf":[{"$ref":"#/components/schemas/Wishes"},{"description":"When this subject should be taught. Useful to forbid PE when it's too hot in the middle of the day, to forbid finance in the evening, or maths as a first lesson"}]}}}]},"Subject":{"description":"A subject is what is taught during a course/lesson, such as mathematics, physics, PE...","type":"object","properties":{"name":{"description":"Name of the subject","type":"string"},"short":{"description":"Short name of the subject, used to be displayed by default on the grid/schedule","type":"string"},"code":{"description":"Code of the subject","type":"string"},"type":{"description":"Type of the subject (e.g. exam, practical work...)","type":"string"},"_extids":{"$ref":"#/components/schemas/ExternalIds"}},"required":["name","code"]},"TimetableClassGroups":{"title":"Groups","description":"Groups are subsets of classes. A group can only have students of one given class. If a course/lesson is followed by students of several classes, you must mix groups with alignment or groups or groups. Groups have unique ID even between classes. The default group ID is prefixed with <classid>:, but this is not mandatory to work (just way better).","type":"object","patternProperties":{"^[a-z0-9:]+$":{"$ref":"#/components/schemas/TimetableClassGroup"}}},"TimetableClassGroup":{"description":"Group object","type":"object","properties":{"name":{"description":"Name of the group","type":"string"},"code":{"description":"Code of the group","type":"string"},"description":{"description":"Description of the group","type":"string"},"free":{"description":"Is this a free group? Free groups deactivate all conflicts with the rest of the class, teacher teaching another lesson or classroom being already occupied.","type":"boolean","default":false,"x-premiumOnly":true},"wishes":{"allOf":[{"$ref":"#/components/schemas/Wishes"},{"description":"Time preferences for this group"}],"x-premiumOnly":true},"parent":{"description":"Parent group, so that this group is a child, inheriting of partition rules from its parent","type":"string","x-premiumOnly":true},"studentsnb":{"description":"Number of students of the group (should be <= to the number of students of the class)","type":"integer","default":0},"students":{"description":"Explicit list of students, only if \"studentsonclasses\" option is set","type":"array","items":{"type":"string"}},"_extids":{"$ref":"#/components/schemas/ExternalIds"}},"required":["code","name"]},"LessonClass":{"allOf":[{"$ref":"#/components/schemas/Lesson"},{"type":"object","properties":{"assoc":{"description":"Associated lessons have groups switching together","type":"array","items":{"$ref":"#/components/schemas/LessonBase"}},"concat":{"description":"Concatenated lessons are strictly happening one after the other, they cannot be cut","type":"array","items":{"$ref":"#/components/schemas/LessonBase"}}}}]},"Lesson":{"allOf":[{"$ref":"#/components/schemas/LessonBase"},{"$ref":"#/components/schemas/PositionTimetable"},{"$ref":"#/components/schemas/Memos"},{"$ref":"#/components/schemas/LessonIdentity"},{"type":"object","properties":{"status":{"description":"Lesson status (planned, draft, canceled, done)","type":"string","enum":["planned","draft","canceled","done"],"x-premiumOnly":true},"weekalt":{"description":"Lessons in alternate week (several weeks but at least one can be free, set \"subject\": \"free\")","type":"array","items":{"$ref":"#/components/schemas/LessonBase"}}}}]},"LessonBase":{"type":"object","properties":{"duration":{"description":"Duration of the lesson, in period number (period = #slot * time_unit)","type":"integer"},"duration_actual":{"description":"Actual duration of the lesson, in minutes (used instead of position start/end when computing accounted duration)","type":"integer","minimum":0,"x-premiumOnly":true},"duration_accounted":{"description":"Accounted duration of the lesson, in minutes (billing purposes)","type":"integer","minimum":0,"x-premiumOnly":true},"modality":{"description":"Lesson modality (in person, remote, hybrid, self-study)","type":"string","enum":["in_person","remote","hybrid","self_study"],"x-premiumOnly":true},"subject":{"description":"Subject ID","type":"string"},"group":{"description":"Group ID","type":"string"},"teachers":{"description":"Teachers (ID), and force that there is NO teacher if null","type":["array","null"],"items":{"type":"string"}},"classroom":{"description":"Classroom ID, and force that there is NO classroom if null. If there are several classrooms, use comma to separate. A valid syntax is <site_id>:<classrom_id>, to specify a site (can be different from the default class site). If no site ID is specified, the default site is the class' one.","type":["string","null"]},"videolink":{"description":"Video link to attend remotely to the lesson","type":"string"},"resources":{"description":"Resources (ID) used by the lesson","type":"array","items":{"type":"string"}}},"required":["subject","duration"]},"PositionTimetable":{"description":"Position used in database for timetables: can be a date (calendar), a weekday (weekly timetable) or a day number (cycle).","allOf":[{"$ref":"#/components/schemas/PositionCommon"},{"type":"object","properties":{"position":{"type":"object","properties":{"day":{"description":"Position of the lesson, can be a date (calendar timetable), a day (weekly timetable) or a day number (cycle)","type":"string","oneOf":[{"format":"date","type":"string"},{"enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"type":"string"},{"pattern":"^[0-9]+$","type":"string"}]},"fixed":{"description":"Is this lesson fixed? (Cannot be moved by the automatic generation algorithm)","type":"boolean","default":false}},"required":["day"]}}}]},"PositionCommon":{"type":"object","properties":{"position":{"type":"object","properties":{"period":{"description":"Period of the lesson (no period and no start/end = holiday)","type":"integer"},"start":{"description":"Exact start hour (format HH:MM)","type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$","examples":[]},"end":{"description":"Exact end hour (format HH:MM)","type":"string","pattern":"^(?:[01]\\d|2[0-3]):[0-5]\\d$","examples":[]}}}}},"Memos":{"type":"object","properties":{"memos":{"description":"Comments on the lesson","type":"array","items":{"$ref":"#/components/schemas/Memo"}}}},"Memo":{"description":"Comments, with different levels of display","type":"object","properties":{"comment":{"description":"Text of the comment","type":"string"},"pub":{"description":"Public who can view this comment","type":"string","enum":["admin","teacher","all"]},"owner":{"description":"Who made this comment","type":"string"},"tstp":{"description":"Timestamp of when this comment was issued/created","type":"integer"}},"required":["comment"]},"LessonIdentity":{"type":"object","properties":{"_id":{"description":"Stable identifier for the lesson, generated from lesson content","type":"string","x-premiumOnly":true},"_osrev":{"description":"Optimistic locking revision counter for the lesson","type":"string","x-premiumOnly":true}}},"TimetableGroupTimeset":{"description":"Class partitions. Groups of a same class are incompatible by default (they could share students) EXCEPT if declared as forming a class partition","type":"array","items":{"description":"The list of groups forming the partition","type":"array","items":{"type":"string"}}},"TimetableGroupSpaceset":{"title":"Group alignment","description":"Group alignment. Groups of different classes working together, as long as they are set on mirrored lessons with same teacher(s) and classroom.","type":"array","items":{"description":"Explicit list of groups in alignement, i.e. strongly linked as the courses of the different classes will be kind of merged together","type":"array","items":{"type":"string"}}},"TimetableGroupGroupset":{"title":"Groups of groups","description":"Groups of groups. Groups of groups allow to create a meta-group regrouping the groups","type":"object","additionalProperties":{"$ref":"#/components/schemas/TimetableGroupGroupsetItem"}},"TimetableGroupGroupsetItem":{"title":"Group of groups definition","description":"Definition of a single group of groups (meta-group)","type":"object","properties":{"name":{"description":"Name of the group of groups","type":"string"},"code":{"description":"Code of the group of groups","type":"string"},"groups":{"description":"Groups constituting the meta-group","type":"array","items":{"type":"string"}}},"required":["name","code","groups"]},"CustomDateTimeFormat":{"type":"string","description":"Date-time value used in timetable metadata. Canonical format is ISO 8601 UTC; legacy format is still accepted during migration.","oneOf":[{"description":"Legacy format kept for backward compatibility (YYYY-MM-DD HH:MM:SS with optional AM/PM).","pattern":"^\\d{4}-\\d{2}-\\d{2} \\d{1,2}:\\d{2}:\\d{2}(?: AM| PM)?$","examples":[],"type":"string"},{"format":"date-time","description":"ISO 8601 format. Canonical storage should be UTC (`Z`).","examples":[],"type":"string"}]},"SchedulesOptions":{"description":"Schedules to restore in schedule module","type":"object","properties":{"customs":{"description":"Entries of schedules to diplay all at once","type":"array","items":{"type":"object","properties":{"name":{"description":"Name of the entry","type":"string"},"schedules":{"description":"List of the schedules to display","type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"},"schedules":{"type":"array","items":{"type":"object","properties":{"type":{"type":"string"},"value":{"type":"string"}}}}}}}}}},"restore":{"description":"automatic restoration of previously displayed scheduled (stored in browser local cookie)","type":"boolean"}}},"Alterations":{"description":"Alterations to store, per week (added/removed)","type":"object","properties":{"added":{"description":"Lessons to add at specific date. That can be a new lesson or a lesson replacing another one (we store everything fields again)","type":"array","items":{"$ref":"#/components/schemas/LessonAlteration"}},"removed":{"description":"Lessons to remove at specific date. As we do not have ID on lessons, we store the complete footprint of the lesson to be removed","type":"array","items":{"$ref":"#/components/schemas/LessonAlteration"}},"subjects":{"description":"Subjects being used in added section, per class","type":"object","additionalProperties":{"type":"object","additionalProperties":{"$ref":"#/components/schemas/Subject"}}},"teachers":{"description":"Teachers being used in added/removed/buffer","type":"object","additionalProperties":{"$ref":"#/components/schemas/TeacherMinimal"}}}},"LessonAlteration":{"allOf":[{"$ref":"#/components/schemas/LessonSchedule"},{"type":"object","properties":{"osubject":{"description":"Complete subject object (copy). A new lesson on a specific date can use a subject which is not existing on the class, so we need to store it there.","$ref":"#/components/schemas/Subject"}}}]},"LessonSchedule":{"allOf":[{"$ref":"#/components/schemas/LessonBase"},{"$ref":"#/components/schemas/PositionDate"},{"$ref":"#/components/schemas/Memos"},{"$ref":"#/components/schemas/LessonIdentity"},{"type":"object","properties":{"class":{"description":"Class of the lesson","type":"string"},"schedid":{"description":"Timetable ID of the lesson","type":"string"},"substitutes":{"description":"Computed substitutions for absent teachers on a lesson (absences module)","type":"object","additionalProperties":{"type":"object","properties":{"substitute":{"description":"Teacher ID acting as substitute","type":"string"},"absence":{"description":"Absence reason of the original teacher","type":"string"},"sticky":{"description":"Absence ID that forced this substitution (when sticky)","type":"string"}}}}},"required":["class","schedid","position"]}]},"PositionDate":{"description":"Position used in API returns: strict date only (YYYY-MM-DD).","allOf":[{"$ref":"#/components/schemas/PositionCommon"},{"type":"object","properties":{"position":{"description":"Position as a date of the lesson on the timetable","type":"object","properties":{"day":{"description":"Date of the lesson","type":"string","format":"date"}},"required":["day"]}}}]},"WhereClause":{"type":"object","description":"Structured filter clause using MongoDB-style operators. Field names support dot-path notation for parent context (e.g., 'sites.name'). Values can be direct (implies $eq) or objects with operators. Multiple operators on same field = implicit AND.","additionalProperties":{"oneOf":[{"description":"Direct value (implies $eq)","type":["string","number","boolean","null"]},{"description":"Operator-based condition","type":"object","properties":{"$eq":{"description":"Equal to"},"$ne":{"description":"Not equal to"},"$gt":{"description":"Greater than","type":["string","number"]},"$gte":{"description":"Greater than or equal","type":["string","number"]},"$lt":{"description":"Less than","type":["string","number"]},"$lte":{"description":"Less than or equal","type":["string","number"]},"$in":{"description":"Value in array","type":"array","items":{"type":["string","number","boolean","null"]}},"$nin":{"description":"Value not in array","type":"array","items":{"type":["string","number","boolean","null"]}},"$exists":{"description":"Field exists","type":"boolean"},"$regex":{"description":"Regex (case-insensitive)","type":"string"},"$contains":{"description":"String/array contains (case-insensitive)"},"$like":{"description":"Dice-based fuzzy match on normalized text (case/accent/punctuation-insensitive)","type":"string"}},"additionalProperties":false}]},"properties":{"$and":{"description":"Logical AND","type":"array","items":{"type":"object"}},"$or":{"description":"Logical OR","type":"array","items":{"type":"object"}},"$not":{"description":"Logical NOT","type":"object"}}},"Event":{"description":"Event object","type":"object","properties":{"title":{"description":"Title of the event (to be displayed)","type":"string"},"start":{"description":"Start of the event (format YYYYMMDDTHHmmSS)","type":"string","pattern":"^\\d{8}T\\d{6}$"},"end":{"description":"End of the event (format YYYYMMDDTHHmmSS)","type":"string","pattern":"^\\d{8}T\\d{6}$"},"rrule":{"$ref":"#/components/schemas/Rrule"},"attendees":{"title":"Users/entities to attend the event","description":"Users/entities to attend the event. It can be a user, a class, a group, a custom name or the whole school (everybody) or anyone who wants to (anyone)","type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["user"]},"id":{"type":"string"},"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"},"roles":{"type":"array","items":{"type":"string"}}},"required":["type","id","first_name","middle_name","last_name"]},{"type":"object","properties":{"type":{"type":"string","enum":["class"]},"id":{"type":"string"},"name":{"type":"string"}},"required":["type","id","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["group"]},"id":{"type":"string"},"name":{"type":"string"},"code":{"type":"string"}},"required":["type","id","name","code"]},{"type":"object","properties":{"type":{"type":"string","enum":["custom"]},"name":{"type":"string"}},"required":["type","name"]},{"type":"object","properties":{"type":{"type":"string","enum":["everybody","anyone"]}},"required":["type"]}]}},"location":{"description":"The location(s) of the event (either a classroom or a custom label)","type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["classroom"]},"name":{"type":"string"},"id":{"type":"string"},"sitename":{"type":"string"}},"required":["type","name","id"]},{"type":"object","properties":{"type":{"type":"string","enum":["custom"]},"name":{"type":"string"}},"required":["type","name"]}]}},"resources":{"description":"The resources to be used/reserved for the event","type":"array","items":{"oneOf":[{"type":"object","properties":{"type":{"type":"string","enum":["resource"]},"id":{"type":"string"},"name":{"type":"string"},"sitename":{"type":"string"}},"required":["type","id"]},{"type":"object","properties":{"type":{"type":"string","enum":["custom"]},"name":{"type":"string"}},"required":["type","name"]}]}},"videolink":{"description":"Video link to remotely attend to the event","type":"string"},"memos":{"description":"Comments on the event","type":"array","items":{"$ref":"#/components/schemas/Memo"}},"color":{"description":"Color of the event (hexadecimal without #, e.g. '1bc5b3')","type":"string","pattern":"^[0-9A-Fa-f]{6}$"},"_osrev":{"description":"Optimistic locking revision counter for the event","type":"string"}},"required":["title","start","end"]},"Rrule":{"description":"Recurrence rule","type":"object","properties":{"freq":{"description":"Frequence of the event (optional). Daily, weekly, monthly.","type":"string","enum":["DAILY","WEEKLY","MONTHLY"]},"interval":{"description":"Recurrence interval (optional, default is 1) - interval of 2 with freq: \"WEEKLY\" means the event repeats every two weeks","type":"integer","default":1},"until":{"description":"End date of reccurrence (UTC format 'YYYYMMDDTHHMMSSZ')","type":"string","pattern":"^\\d{8}T\\d{6}Z$"},"count":{"description":"Total number of occurrences before the recurrence stops","type":"integer"},"bysetpos":{"description":"Specific occurrence position (e.g., the 3rd instance of a specific day)","type":"array","items":{"type":"integer"}}}},"AbsenceTeacher":{"allOf":[{"$ref":"#/components/schemas/Absence"},{"description":"Absence of the teacher","type":"object","properties":{"subjects":{"description":"Absence only for these subjects. A teacher can only be unavailable for chemistry but ok for physics","type":"array","items":{"type":"string"}},"classes":{"description":"Absence only for those classes. A teacher can only be allergic to one specific class","type":"array","items":{"type":"string"}},"substitutes":{"description":"All substitution rules","type":"array","items":{"$ref":"#/components/schemas/AbsenceTeacherSubstitute"}},"status":{"$ref":"#/components/schemas/AbsenceTeacherStatus"}}}]},"Absence":{"type":"object","properties":{"date_start":{"description":"Start date (YYYY-MM-DD)","type":"string","format":"date"},"date_end":{"description":"End date (YYYY-MM-DD)","type":"string","format":"date"},"reason":{"description":"Reason of the absence (ID refering to a translation key, OR custom label)","type":"string"},"tstp":{"description":"Creation timestamp (since EPOCH)","type":"integer"},"createdby":{"description":"User creating this absence","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"comment":{"description":"Free comment","type":"string"},"hours":{"description":"Specific optional hour spans (all day/date, or with specific hours)","type":"array","items":{"type":"object","properties":{"begin":{"description":"Start in minutes","type":"integer"},"end":{"description":"End in minutes","type":"integer"},"day":{"description":"Date of the day (YYYY-MM-DD)","type":"string","format":"date"}},"required":["day"]}},"statusby":{"description":"User last modifying the status","oneOf":[{"type":"string"},{"properties":{"first_name":{"type":"string"},"middle_name":{"type":"string"},"last_name":{"type":"string"}}}]},"statuststp":{"description":"Status update timestamp (since EPOCH)","type":"number"}},"required":["date_start","reason"]},"AbsenceTeacherSubstitute":{"description":"Substitution rule for a teacher's absence","type":"object","oneOf":[{"type":"object","properties":{"substitute":{"description":"Substitute teacher's name","type":"string"},"date_start":{"description":"Start date of the substitution rule (YYYY-MM-DD)","type":"string","format":"date"},"date_end":{"description":"End date of the substitution rule (YYYY-MM-DD)","type":"string","format":"date"},"hours":{"description":"Time slots of the substitution rule","type":"array","items":{"type":"object","properties":{"begin":{"description":"Start time of the slot (in minutes)","type":"number"},"end":{"description":"End time of the slot (in minutes)","type":"number"},"day":{"description":"Date concerned (YYYY-MM-DD)","type":"string","format":"date"}},"required":["day"]}},"classes":{"description":"List of classes concerned by the rule","type":"array","items":{"type":"string"}},"subjects":{"description":"List of subjects concerned by the rule","type":"array","items":{"type":"string"}},"comment":{"description":"Comment or additional information about the rule","type":"string"}},"required":["substitute","date_start"]},{"type":"object","properties":{"substitute":{"description":"Substitute teacher's name","type":"string"},"course":{"description":"Specific substituted lessons. As we don't use ID on lessons, we need to store a complete footprint","type":"object","properties":{"class":{"description":"Class of the substituted lesson","type":"string"},"subject":{"description":"Subject of the substituted lesson","type":"string"},"group":{"description":"Group of the substituted lesson (optional)","type":"string"},"day":{"description":"Day of the week of the substituted lesson","type":"string"},"period":{"description":"Period of the substituted lesson","type":"integer"}},"required":["class","subject","day","period"]}},"required":["substitute","course"]}]},"AbsenceTeacherStatus":{"description":"Status of the absence:\n- `ok`: validated\n- `rejected`: refused by administration (no authorization)\n- `aborted`: canceled by teacher/admin\n- `ko`: canceled for technical reason","type":"string","enum":["ok","rejected","pending","aborted","ko"],"default":"ok","examples":["ok","rejected","aborted","ko"]},"Panel":{"description":"Display panel with lessons of the day (for entrance hall, classroom...)","type":"object","properties":{"label":{"description":"Panel label (for internal reference use)","type":"string"},"title":{"description":"Title of the panel, to be displayed","type":"string"},"spanhours":{"description":"How many hours to show starting from now (0 = all day)","type":"integer","default":0},"messages":{"description":"Messages to display on the panel","type":"array","items":{"type":"object","properties":{"text":{"description":"Text of the message","type":"string"},"start":{"description":"Start hour","type":"string","pattern":"^\\d{2}:\\d{2}$","examples":[]},"end":{"description":"End hour","type":"string","pattern":"^\\d{2}:\\d{2}$","examples":[]}},"required":["text","start","end"]}},"fontsize":{"description":"Font size","type":"string","enum":["small","medium","large"],"default":"medium"},"formatname":{"description":"Format of the teachers' name (like First name first or last, or Mr. Lastname, etc.)","type":"string","enum":["firstmiddlelast","lastmiddlefirst","titlelast","titlefirst"],"default":"firstmiddlelast"},"title_name_m":{"description":"Title for Mr. (localized)","type":"string"},"title_name_f":{"description":"Title for Mrs. (localized)","type":"string"},"colorbackground":{"description":"Background color","type":"string"},"colorfont":{"description":"Font color","type":"string"},"colorodd":{"description":"Font color for odd lines","type":"string"},"coloreven":{"description":"Font color for even lines","type":"string"},"topline":{"description":"What to display in header (order matters)","type":"array","items":{"type":"string","enum":["title","logo","date"]}},"columns":{"description":"What columns to display in the lesson grid (order matters)","type":"array","items":{"type":"string","enum":["room","classes","teachers","subject","hours"]}},"filters":{"description":"Explicit items to display, can be levels, classes, sites, or classrooms. Empty = all","type":"object","properties":{"levels":{"description":"Levels to display (= all classes from this level)","type":"array","items":{"type":"string"}},"classes":{"description":"Classes (ID) to display","type":"array","items":{"type":"string"}},"sites":{"description":"Sites (ID) to display (= all classrooms from this site)","type":"array","items":{"type":"string"}},"classrooms":{"description":"Classrooms (ID) to display","type":"array","items":{"type":"string"}}}},"exclusions":{"description":"Specific items to exclude from display","type":"object","properties":{"subjects":{"description":"Specific subjects (ID) to exclude","type":"array","items":{"type":"string"},"examples":[]},"types":{"description":"Specific types to exclude","type":"array","items":{"type":"string"},"examples":[]}}}}},"AbsenceClass":{"allOf":[{"$ref":"#/components/schemas/Absence"},{"description":"Absence of the class","type":"object","properties":{"status":{"description":"Status of the absence","type":"string","enum":["ok","aborted"]}}}]},"AbsenceStaff":{"allOf":[{"$ref":"#/components/schemas/Absence"},{"description":"Absence of the staff member","type":"object","properties":{"subjects":{"description":"Specific subjects (ID) to exclude. For example, the staff member can only be absent to PE course","type":"array","items":{"type":"string"}},"status":{"$ref":"#/components/schemas/AbsenceStaffStatus"}}}]},"AbsenceStaffStatus":{"description":"Status of the absence:\n- `ok`: validated\n- `rejected`: refused by administration (no authorization)\n- `aborted`: canceled by staff member/admin\n- `ko`: canceled for technical reason","type":"string","enum":["ok","rejected","pending","aborted","ko"],"default":"ok","examples":["ok","rejected","aborted","ko"]},"AbsenceStudent":{"allOf":[{"$ref":"#/components/schemas/Absence"},{"description":"Absence of the student","type":"object","properties":{"subjects":{"description":"Specific subjects (ID) to exclude. For example, the student can only be absent to PE course","type":"array","items":{"type":"string"}},"status":{"$ref":"#/components/schemas/AbsenceStudentStatus"}}}]},"AbsenceStudentStatus":{"description":"Status of the absence:\n- `ok`: validated\n- `rejected`: refused by administration (no authorization)\n- `aborted`: canceled by student/admin\n- `ko`: canceled for technical reason","type":"string","enum":["ok","rejected","pending","aborted","ko"],"default":"ok","examples":["ok","rejected","aborted","ko"]},"StaffingGrids":{"description":"Multiple grids, by numeric id, each with its own active date ranges.","type":"object","additionalProperties":{"$ref":"#/components/schemas/StaffingGrid"}},"StaffingGrid":{"description":"Definition of the grid : days, periods and generic availability wishes. Acts as the template for building the weekly schedule.","type":"object","properties":{"dates":{"description":"Inclusive date ranges when this grid is active, as an array of [begin,end] pairs (YYYY-MM-DD).","type":"array","items":{"type":"array","minItems":2,"maxItems":2,"items":{"type":"string","format":"date"}}},"days":{"description":"List of days (e.g. monday, tuesday, ...)","type":"array","items":{"type":"string"}},"periods":{"description":"List of periods (time slots).","type":"array","items":{"type":"object","properties":{"begin":{"description":"Period start time (HH:MM)","type":"string"},"end":{"description":"Period end time (HH:MM)","type":"string"},"label":{"description":"Optional label for the period.","type":"string"},"comment":{"description":"Optional comment for the period.","type":"string"}},"required":["begin","end"]}},"wishes":{"$ref":"#/components/schemas/Wishes"}},"required":["days","periods"]},"StaffingSites":{"description":"List of sites or sites, including names and relative distances, used to compute feasibility and travel times.","type":"object","additionalProperties":{"type":"object","properties":{"name":{"description":"Site name.","type":"string"},"distances":{"description":"Distances to other sites (by id, in meters).","type":"object","additionalProperties":{"type":"number"}}},"required":["name"]}},"StaffingAssignments":{"description":"Catalog of possible assignments (duties/positions to be covered). Each assignment defines compatibility with others, minimum/maximum required staff, priority level, and optional wishes per shift.","type":"object","additionalProperties":{"$ref":"#/components/schemas/StaffingAssignment"}},"StaffingAssignment":{"type":"object","properties":{"name":{"description":"Assignment name.","type":"string"},"compatibility":{"description":"List of compatible assignments (by id).","type":"array","items":{"type":"string"}},"req":{"type":"integer","minimum":0,"description":"Hard minimum staff to cover."},"ideal":{"type":"integer","minimum":0,"description":"Preferred headcount (≥ required)."},"site":{"description":"Site ID where this assignment takes place (optional).","type":"string"},"priority":{"description":"Assignment priority.","type":"string","enum":["high","normal","low"]},"needs":{"$ref":"#/components/schemas/StaffingNeeds"},"allowed_staff":{"description":"List of allowed staff ids for this assignment (if empty, all staff are allowed).","type":"array","items":{"type":"string"}}},"required":["name"]},"StaffingNeeds":{"description":"List of staffing needs, per grid.","additionalProperties":{"type":"object","properties":{"spans":{"description":"Per-assignment exact needs by time spans. Spans should not overlap and must have begin < end (enforced at application level).","type":"array","items":{"$ref":"#/components/schemas/StaffingNeedSpan"}}}}},"StaffingNeedSpan":{"type":"object","description":"Exact staffing need for a time span. If headcount=0, no staff is required in that window.","properties":{"day":{"description":"Day or date","type":"string","oneOf":[{"format":"date","type":"string"},{"enum":["monday","tuesday","wednesday","thursday","friday","saturday","sunday"],"type":"string"}]},"begin":{"type":"string","description":"Start time (HH:MM, 24h).","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"end":{"type":"string","description":"End time (HH:MM, 24h).","pattern":"^([01]\\d|2[0-3]):[0-5]\\d$"},"headcount":{"type":"integer","minimum":0,"description":"Exact number of staff required for this window (0 = no need)."}},"required":["begin","end","headcount"],"additionalProperties":false},"StaffingDisplayOrder":{"description":"Preferred display order of assignments in the user interface, e.g. in the weekly grid view.","type":"object","properties":{"assignments":{"description":"Order of assignments (array of assignment ids).","type":"array","items":{"type":"string"}}}},"StaffingStaff":{"description":"List of staff members included in this module, with their basic information (identifiers, names, etc.).","type":"object","additionalProperties":{"$ref":"#/components/schemas/StaffingStaffMember"}},"StaffingStaffMember":{"type":"object","properties":{"first_name":{"description":"Staff member's first name.","type":"string"},"middle_name":{"description":"Staff member's middle name.","type":"string"},"last_name":{"description":"Staff member's last name.","type":"string"},"virtual_name":{"description":"Staff member's virtual name = a staff member not yet hired.","type":"string"},"color":{"description":"Hex color for visual identification in the UI (e.g., 27AE60).","type":"string","pattern":"^[0-9A-Fa-f]{6}$"}},"required":["first_name","last_name"]},"StaffingScheduleDate":{"description":"Shift schedule for a specific date and specific assignment.","type":"object","additionalProperties":{"description":"Shift schedule for a specific date, specific assignment, by period (mapped to the grid).","type":"array","items":{"type":["object","null"],"properties":{"comment":{"description":"Optional comment for this entry.","type":"string"},"staff":{"description":"List of assigned staff ids.","type":"array","items":{"type":"string"}},"locked_staff":{"description":"List of locked staff ids (cannot be changed).","type":"array","items":{"type":"string"}}}}}},"SubjectFull":{"allOf":[{"$ref":"#/components/schemas/Subject"},{"type":"object","properties":{"parent":{"description":"Parent subject (another subject)","type":"string"},"family":{"description":"Family of the subject","type":"string"},"color":{"description":"Color (if not defined, will be automatically computed based on name hash)","type":"string"}}}],"required":["code","name"]},"User":{"description":"User","type":"object","allOf":[{"$ref":"#/components/schemas/UserEditable"},{"type":"object","properties":{"login":{"description":"Login","type":"string"},"password":{"description":"Password (hashed + salt + peppper)","type":"string"},"auth":{"$ref":"#/components/schemas/Auth"}}}],"required":["first_name","last_name","login","roles"]},"UserEditable":{"description":"User fields editable through the main admin user update flows, excluding credentials and provider-link metadata. auth.breakGlass remains editable here.","type":"object","allOf":[{"$ref":"#/components/schemas/UserMinimal"},{"$ref":"#/components/schemas/Placements"},{"type":"object","properties":{"roles":{"description":"List of roles","type":"array","items":{"type":"string","enum":["superadmin","admin","staf","teacher","student"]}},"customrole":{"description":"Custom role","type":"string"},"servicehours":{"description":"Service hours, i.e. the number of hours the teacher should teach","type":"integer"},"external":{"description":"External teacher flag (only stored if true)","type":"boolean","x-premiumOnly":true},"subjects":{"description":"Subjects to be taught by the teacher (useful for automatic suggestions)","type":"object","additionalProperties":{"type":"object","properties":{"name":{"description":"Subject name","type":"string"},"code":{"description":"Subject code","type":"string"}},"required":["name","code"]}},"wishes":{"allOf":[{"$ref":"#/components/schemas/WishesTeachers"},{"description":"Teacher's wishes/availabilities"}]},"auth":{"$ref":"#/components/schemas/AuthEditable"},"schedules_options":{"$ref":"#/components/schemas/SchedulesOptions"},"_extids":{"$ref":"#/components/schemas/ExternalIds"}}}]},"Placements":{"type":"object","properties":{"placements":{"description":"Student placement (classes/groups, during school years), by ID = school year","type":"object","additionalProperties":{"type":"array","items":{"$ref":"#/components/schemas/Placement"}}}}},"AuthEditable":{"description":"Editable authentication flags exposed in the generic user update flow","type":"object","properties":{"breakGlass":{"description":"Allow local password login even in OIDC-only mode (emergency access)","type":"boolean"}}},"Auth":{"description":"Authentication metadata for a user","type":"object","allOf":[{"$ref":"#/components/schemas/AuthEditable"},{"type":"object","properties":{"providers":{"description":"External identity providers linked to this user","type":"array","items":{"$ref":"#/components/schemas/OidcProviderLink"}}}}]},"OidcProviderLink":{"description":"Link to an external OIDC identity provider","type":"object","properties":{"type":{"description":"Provider type identifier","type":"string","enum":["oidc"],"default":"oidc"},"providerName":{"description":"Provider name (azure, keycloak, google, etc.)","type":"string"},"issuer":{"description":"OIDC issuer URL","type":"string","format":"uri"},"subject":{"description":"OIDC subject claim (sub) - stable user ID from IdP","type":"string"},"tenantId":{"description":"Azure tenant ID (tid claim) if applicable","type":"string"},"objectId":{"description":"Azure object ID (oid claim) if applicable","type":"string"},"emailAtLink":{"description":"Email address at the time of linking (for audit)","type":"string","format":"email"},"linkedAt":{"description":"ISO timestamp when the link was created","type":"string","format":"date-time"}},"required":["type","issuer","subject","linkedAt"]},"Family":{"description":"A family is a grouping of subjects sharing common characteristics, often used to categorize or classify subjects within a broader context. For example, a family could represent a department (like Sciences or Humanities), a curriculum area, or any other logical grouping that helps organize subjects based on their similarities or relationships.","type":"object","properties":{"name":{"description":"Name of the family","type":"string"},"code":{"description":"Code of the family","type":"string"},"_extids":{"$ref":"#/components/schemas/ExternalIds"}},"required":["name"]},"SchoolConfig":{"type":"object","properties":{"defaults":{"description":"Default new timetable configuration","type":"object","properties":{"time_unit":{"type":"integer","default":1},"time_period":{"type":"integer","default":60},"displaymode":{"type":"string","enum":["hours","periods","calendar"],"default":"hours"}}},"firstday":{"description":"First day of the week, 0 = Sunday, 1 = Monday","type":"integer","enum":[0,1],"default":1},"levels":{"type":"array","items":{"type":"string"}},"campuses":{"description":"Configured campus labels","type":"array","x-premiumOnly":true,"items":{"type":"string"}},"opening_hours":{"description":"Global school opening hours by day","type":"object","patternProperties":{"^(monday|tuesday|wednesday|thursday|friday|saturday|sunday)$":{"type":"object","properties":{"from":{"type":"string","pattern":"^([0-1][0-9]|2[0-3]):[0-5][0-9]$"},"to":{"type":"string","pattern":"^([0-1][0-9]|2[0-3]):[0-5][0-9]$"}},"required":["from","to"]}}},"login":{"description":"Pattern to generate user's login","type":"string","enum":["firstlast","lastfirst","idnumber"],"default":"firstlast","readOnly":true},"middlename":{"description":"Activate middle name support","type":"boolean","default":false},"namecapitalize":{"description":"Name parts to capitalize (first name, middle name, last name)","type":"array","items":{"type":"string","enum":["first","middle","last"]},"uniqueItems":true,"default":[]},"weekalt":{"description":"Support for alternate weeks","type":"string","enum":["numbers","letters","no"],"default":"numbers"},"subjecttypemandatory":{"description":"Require a type for each subject assignment","type":"boolean","default":false},"nocommonsubjects":{"description":"Deactivate common country subjects","type":"boolean","default":false},"wishes":{"description":"Support for teachers' wishes","type":"string","enum":["week","calendar","both","no"]},"creation":{"allOf":[{"$ref":"#/components/schemas/CustomDateTimeFormat"},{"description":"Creation date of the school account"}]},"name":{"description":"School account name","type":"string"},"uai":{"description":"Établissement code (UAI/RNE). Initialized from the UAJ code of an STS-web import. Used as the OneRoster Org identifier when present.","type":"string"},"country":{"description":"Account country","type":"string"},"types":{"description":"Types of subjects","type":"array","items":{"type":"string"}},"current_school_year":{"description":"Current school year id (from school_years)","type":"string"},"timezone":{"description":"School timezone (useful for iCal generation)","type":"string"},"studentrestriction":{"description":"View restriction of lessons, in weeks, for students (0 = none)","type":"integer","default":0},"teacherrestriction":{"description":"Account restriction for teachers, preventing them to see other information besides their owns","type":"boolean","default":false},"loginrestriction":{"description":"Login restriction by role: prevent specified user roles from logging in. Users with multiple roles can still login if at least one role is allowed","type":"array","items":{"type":"string","enum":["teacher","staff","student"]},"uniqueItems":true,"default":[],"x-accountLevel":"staffing"},"roles":{"type":"object","properties":{"^[a-z0-9-]+$":{"description":"Custom roles for admin, restricting their access to the platform (requires custom roles option)","type":"object","properties":{"name":{"type":"string"},"exclude_modules":{"type":"array","items":{"type":"string"}},"exclude_endpoints":{"type":"array","items":{"type":"string"}}}}},"x-premiumOnly":true},"extsync":{"$ref":"#/components/schemas/SchoolConfigExtsync"},"oidc":{"$ref":"#/components/schemas/SchoolConfigOidc"},"type":{"description":"Type of account (school, premium, etc.)","x-permission":"superadmin-only","type":"string","enum":["lite","staffing","school","schoolplus","premium","gold"],"default":"school"},"provider":{"description":"List of providers allowed on the platform","x-permission":"superadmin-only","type":"array","items":{"type":"string"}},"studentsonclasses":{"description":"Reverse students/classes association (students first)","x-permission":"superadmin-only","type":"boolean","default":false},"multipleactivation":{"description":"Allow multiple simultaneous timetable activations (non-premium accounts)","x-permission":"superadmin-only","type":"boolean","default":false},"cycletimetables":{"description":"Allow cycle timetables, but not calendar ones (non-premium accounts)","x-permission":"superadmin-only","type":"boolean","default":false},"customroles":{"description":"Activate support for custom roles","x-permission":"superadmin-only","type":"boolean","default":false},"extramodules":{"description":"Enable additional modules","x-permission":"superadmin-only","type":"array","items":{"type":"string"},"default":[]},"snapshotsmax":{"description":"Number of allowed snapshots (0 = disabled)","x-permission":"superadmin-only","type":"number","default":0},"logsmax":{"description":"Number of days to keep logs (0 = disabled)","x-permission":"superadmin-only","type":"integer","default":0},"collab":{"description":"Activate collaboration features","x-permission":"superadmin-only","type":"boolean","default":false},"algoinstance":{"description":"Force use of a dedicated scheduling instance","x-permission":"superadmin-only","type":"string","enum":["c7g.4xlarge","c7g.8xlarge","c7g.12xlarge","c7g.16xlarge"]},"linkedaccounts":{"title":"Linked accounts to this account","description":"Allow seeing shared teachers/classrooms occupation from linked accounts","x-permission":"superadmin-only","type":"array","items":{"type":"string"}},"accesskey":{"description":"Private unique random key used to salt","type":"string","readOnly":true}},"required":["accesskey","name","country"]},"SchoolConfigExtsync":{"type":"object","title":"External systems synchronization configuration","description":"Configuration for synchronization with external systems (Auriga, Aimaira, Neil, etc.)","properties":{"default":{"type":"string","description":"Default system to use for synchronization","enum":["auriga","aimaira","neil"]},"systems":{"$ref":"#/components/schemas/SchoolConfigExtsyncSystems"},"sync":{"$ref":"#/components/schemas/SchoolConfigExtsyncSync"},"export":{"$ref":"#/components/schemas/SchoolConfigExtsyncExport"},"schedules":{"$ref":"#/components/schemas/SchoolConfigExtsyncSchedules"}},"x-premiumOnly":true},"SchoolConfigExtsyncSystems":{"type":"object","description":"External systems configurations","properties":{"aurion":{"$ref":"#/components/schemas/SchoolConfigExtsyncSystemAurion"},"auriga":{"$ref":"#/components/schemas/SchoolConfigExtsyncSystemAuriga"},"oneroster":{"$ref":"#/components/schemas/SchoolConfigExtsyncSystemOneroster"}},"additionalProperties":{"$ref":"#/components/schemas/SchoolConfigExtsyncSystemGeneric"}},"SchoolConfigExtsyncSystemAurion":{"type":"object","title":"Aurion system configuration","description":"Configuration for Aurion (Hyperplanning) ERP system","properties":{"enabled":{"type":"boolean","description":"Enable Aurion integration","default":false},"configuration":{"type":"object","description":"Aurion-specific configuration","properties":{"domain":{"type":"string","description":"Aurion domain"},"login":{"type":"string","description":"Aurion login"},"password":{"type":"string","description":"Aurion password (sensitive)"},"favori_interventions":{"type":"string","description":"Favori ID for interventions (initial importation/live synchronization)"},"favori_interventions_verification":{"type":"string","description":"Optional favori ID used to manually verify exported interventions"},"favori_statuts_intervention":{"type":"string","description":"Favori ID for intervention statuses"},"favori_matieres":{"type":"string","description":"Favori ID for subjects"},"favori_cours":{"type":"string","description":"Favori ID for courses"},"favori_types_activite":{"type":"string","description":"Favori ID for activity types"},"favori_intervenants":{"type":"string","description":"Favori ID for teachers"},"favori_groupes":{"type":"string","description":"Favori ID for groups"},"favori_ressources":{"type":"string","description":"Favori ID for resources/classrooms"},"database":{"type":"string","description":"Database name"}},"required":["domain","login","password","database"]},"defaults":{"type":"object","description":"Default Aurion values used during Omniscol lesson export","properties":{"activityType":{"type":"string","description":"Default Aurion activity type code"},"interventionStatus":{"type":"string","description":"Default Aurion intervention status code"}}},"mappings":{"allOf":[{"$ref":"#/components/schemas/SchoolConfigExtsyncMappings"}],"description":"Stored Aurion mappings, including status mappings under mappings.status"}}},"SchoolConfigExtsyncMappings":{"type":"object","description":"Generic ExtSync mappings by mapping key and Omniscol source id/value (for example: subjects, teachers, classes, groups, classrooms, status)","additionalProperties":{"$ref":"#/components/schemas/SchoolConfigExtsyncMappingMap"}},"SchoolConfigExtsyncMappingMap":{"type":"object","description":"Generic ExtSync mapping map keyed by the Omniscol source id/value","additionalProperties":{"$ref":"#/components/schemas/SchoolConfigExtsyncMappingEntry"}},"SchoolConfigExtsyncMappingEntry":{"type":"object","description":"Generic ExtSync mapping entry stored by Omniscol between a local value/entity and an external ERP value/entity","properties":{"external_id":{"type":"string","description":"Canonical external entity identifier, independent from ERP-native field names"},"external_code":{"type":"string","description":"Optional external code used for display and fallback resolution"},"external_label":{"type":"string","description":"Optional external label used for display and fallback resolution"},"create":{"type":"boolean"},"ignore":{"type":"boolean"}},"additionalProperties":true},"SchoolConfigExtsyncSystemAuriga":{"type":"object","title":"Auriga system configuration","description":"Configuration for Auriga ERP system (Keycloak OAuth2 + REST API)","properties":{"enabled":{"type":"boolean","description":"Enable Auriga integration","default":false},"configuration":{"type":"object","description":"Auriga-specific configuration","properties":{"apiBaseUrl":{"type":"string","description":"Auriga API base URL (e.g., https://auriga-test.epita.fr)","format":"uri"},"keycloakServer":{"type":"string","description":"Keycloak server hostname (e.g., ionisepita-auth.np-auriga.nfrance.net)"},"realm":{"type":"string","description":"Keycloak realm (e.g., npionisepita)"},"clientId":{"type":"string","description":"OAuth2 client ID"},"clientSecret":{"type":"string","description":"OAuth2 client secret (sensitive)"},"username":{"type":"string","description":"User login for password grant flow"},"password":{"type":"string","description":"User password for password grant flow (sensitive)"},"scope":{"type":"string","description":"OAuth2 scope (default: offline_access)","default":"offline_access"},"defaults":{"type":"object","description":"Default codes used by Omniscol when exporting lessons to Auriga","properties":{"activityType":{"type":"string","description":"Default activity type code (e.g., CM)"},"interventionStatus":{"type":"string","description":"Default intervention status code (e.g., PLANIFIE)"}},"additionalProperties":false}},"required":["apiBaseUrl","keycloakServer","realm","clientId","clientSecret","username","password"]},"mappings":{"allOf":[{"$ref":"#/components/schemas/SchoolConfigExtsyncMappings"}],"description":"Stored Auriga mappings, including status mappings under mappings.status"}}},"SchoolConfigExtsyncSystemOneroster":{"type":"object","title":"OneRoster system configuration","description":"Configuration for OneRoster (IMS Global 1.2 Rostering + Advanced Groups) integration, as producer and/or consumer","properties":{"enabled":{"type":"boolean","description":"Enable OneRoster integration","default":false},"configuration":{"type":"object","description":"OneRoster-specific configuration","properties":{"mode":{"type":"string","description":"Transport: REST API or OneRoster CSV bundle (zip)","enum":["rest","csv"],"default":"rest"},"direction":{"type":"string","description":"Integration direction: consume (SIS to Omniscol), produce (Omniscol to LMS/ENT), or both","enum":["consume","produce","both"],"default":"consume"},"apiBaseUrl":{"type":"string","description":"Remote provider base URL in consumer mode, e.g. https://.../ims/oneroster/rostering/v1p2","format":"uri"},"tokenUrl":{"type":"string","description":"OAuth2 token endpoint for client_credentials grant (consumer mode)","format":"uri"},"clientId":{"type":"string","description":"OAuth2 client ID (consumer mode)"},"clientSecret":{"type":"string","description":"OAuth2 client secret (sensitive, consumer mode)"},"scope":{"type":"string","description":"OAuth2 scope requested from the remote provider (consumer mode)"},"profile":{"type":"string","description":"OneRoster profile: core Rostering 1.2, additive Advanced Groups, or French K12 mapping","enum":["core","groups","frenchK12"],"default":"core"}},"required":["mode","direction"]},"mappings":{"allOf":[{"$ref":"#/components/schemas/SchoolConfigExtsyncMappings"}],"description":"Stored OneRoster mappings (external sourcedId to local id), keyed by entity type"}}},"SchoolConfigExtsyncSystemGeneric":{"type":"object","description":"Configuration for other external systems","additionalProperties":true},"SchoolConfigExtsyncSync":{"type":"object","description":"Per-entity synchronization settings","propertyNames":{"enum":["groups","subjects","classrooms","teachers"]},"patternProperties":{"^(groups|subjects|classrooms|teachers)$":{"$ref":"#/components/schemas/SchoolConfigExtsyncSyncEntity"}},"additionalProperties":false},"SchoolConfigExtsyncSyncEntity":{"type":"object","description":"Synchronization settings for a single entity type","properties":{"system":{"type":"string","description":"System to sync from (auriga, aimaira, neil, etc.)"},"creation":{"type":"boolean","description":"Allow creating new entities locally (not synced from external system)","default":true},"update":{"type":"boolean","description":"Allow updating entity attributes locally (diverge from external system)","default":true}},"additionalProperties":false},"SchoolConfigExtsyncExport":{"type":"object","description":"Per-entity export settings to external systems","properties":{"lessons":{"$ref":"#/components/schemas/SchoolConfigExtsyncExportLessons"}}},"SchoolConfigExtsyncExportLessons":{"type":"object","description":"Export configuration for lessons/courses to external systems. The key is the system (auriga, aurion, aimaira, neil, etc.).","additionalProperties":{"$ref":"#/components/schemas/SchoolConfigExtsyncExportLessonsSystem"}},"SchoolConfigExtsyncExportLessonsSystem":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Enable lessons export to this system","default":false},"rt":{"type":"boolean","description":"Enable real-time differential export (triggered on lesson modifications)","default":false},"full":{"$ref":"#/components/schemas/SchoolConfigExtsyncExportLessonsFull"}}},"SchoolConfigExtsyncExportLessonsFull":{"type":"object","properties":{"enabled":{"type":"boolean","description":"Enable full export (all lessons) on schedule","default":false},"time":{"type":"array","items":{"type":"string","pattern":"^\\d{2}:\\d{2}$"}}}},"SchoolConfigExtsyncSchedules":{"type":"object","description":"Automation schedule / refresh policy (used by jobs), to import lessons to display.","properties":{"enabled":{"type":"boolean","description":"Enable schedules synchronization","default":true},"system":{"type":"string","description":"External system to sync schedules from (aurion, auriga, etc.)"},"refresh_per_day":{"type":"integer","minimum":0,"default":0,"description":"How many times per day to refresh (0 = disabled)."}},"additionalProperties":false},"SchoolConfigOidc":{"description":"OpenID Connect configuration for external authentication (Azure AD, Keycloak, Google)","type":"object","x-premiumOnly":true,"properties":{"enabled":{"description":"Enable OIDC authentication for this school","type":"boolean","default":false},"providerType":{"description":"Type of OIDC provider (for UI hints and special handling)","type":"string","enum":["azure","keycloak","google","generic"],"default":"generic"},"providerName":{"description":"Display name for the provider (shown on login button)","type":"string","default":"SSO"},"issuer":{"description":"OIDC Issuer URL (discovery endpoint = issuer + /.well-known/openid-configuration)","type":"string","format":"uri"},"clientId":{"description":"OAuth2 Client ID","type":"string"},"clientSecret":{"description":"OAuth2 Client Secret (stored encrypted)","type":"string"},"scopes":{"description":"OAuth2 scopes to request","type":"array","items":{"type":"string"},"default":["openid","email","profile"]},"allowedDomains":{"description":"Restrict login to users with email matching these domains","type":"array","items":{"type":"string"}},"ssoOnly":{"description":"Force SSO-only login (except break-glass)","type":"boolean","default":false},"tenantId":{"description":"Azure tenant ID (shortcut, can be derived from issuer)","type":"string"}}},"Translations":{"description":"Custom translation overloading/redefinitions","type":"object","properties":{"rules":{"description":"Generic rule of expression to replace by other expression","type":"array","items":{"$ref":"#/components/schemas/TranslationRule"}},"keys":{"description":"Replacement of an internal translation key by a custom user-defined string","type":"object","additionalProperties":{"type":"string"}}},"x-premiumOnly":true},"TranslationRule":{"type":"object","properties":{"from":{"description":"Expression to be replaced","type":"string"},"to":{"description":"Replacement string","type":"string"},"alpha":{"description":"Case sensitive?","type":"boolean","default":false},"regexp":{"description":"Is it a regular expression?","type":"boolean","default":false},"complete":{"description":"Only match the complete expression (no substring match)?","type":"boolean","default":false}},"required":["from","to"]},"SchoolConfigExtsyncSystem":{"description":"Configuration for a single external system","oneOf":[{"$ref":"#/components/schemas/SchoolConfigExtsyncSystemAurion"},{"$ref":"#/components/schemas/SchoolConfigExtsyncSystemAuriga"},{"$ref":"#/components/schemas/SchoolConfigExtsyncSystemOneroster"},{"$ref":"#/components/schemas/SchoolConfigExtsyncSystemGeneric"}]}}},"security":[{"bearerAuth":[]},{"cookieAuth":[]},{"queryAuth":[]}]}