{ "openapi": "3.1.0", "info": { "title": "CMS API", "description": "", "contact": { "name": "University of Helsinki", "email": "mooc@cs.helsinki.fi" }, "license": { "name": "Apache-2.0", "identifier": "Apache-2.0" }, "version": "0.1.0" }, "paths": { "/api/v0/cms/ai-suggestions/paragraph": { "post": { "tags": ["cms_ai_suggestions"], "summary": "\nPOST `/api/v0/cms/ai-suggestions/paragraph` - Generate AI suggestions for a CMS paragraph.\n\nThis endpoint is intended for CMS editors. It requires the user to have edit access\nto the referenced page when `context.page_id` is provided, otherwise it falls back\nto requiring a teaching role for some course via `Res::AnyCourse`.", "operationId": "requestParagraphSuggestions", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ParagraphSuggestionRequest" } } }, "required": true }, "responses": { "200": { "description": "Generated paragraph suggestions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ParagraphSuggestionResponse" } } } } } } }, "/api/v0/cms/chapters/{course_id}/all-chapters-for-course": { "get": { "tags": ["cms_chapters"], "summary": "\nGET `/api/v0/cms/chapters/{course_id}/all-chapters-for-course` - Gets all chapters with a course_id", "operationId": "getAllChaptersByCourseId", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course chapters", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DatabaseChapter" } } } } } } } }, "/api/v0/cms/code-giveaways/by-course/{course_id}": { "get": { "tags": ["cms_code_giveaways"], "summary": "\nGET `/api/v0/cms/code-giveaways/by-course/:course_id` - Returns code giveaways for a course.", "operationId": "getCmsCodeGiveawaysByCourse", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Code giveaways for course", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CodeGiveaway" } } } } } } } }, "/api/v0/cms/course-instances/{course_instance_id}": { "get": { "tags": ["cms_course_instances"], "summary": "\nGET `/api/v0/cms/course-instances/:course_instance` - Gets a course instance by id.", "operationId": "getCmsCourseInstance", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course instance", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseInstance" } } } } } } }, "/api/v0/cms/course-instances/{course_instance_id}/organization": { "get": { "tags": ["cms_course_instances"], "summary": "\nGET `/api/v8/course-instances/:course_instance` - Gets a course instance by id.\n\n# Example\nRequest: `GET /api/v8/course-instances/e051ddb5-2128-4215-adda-ebd74a0ea46b`", "operationId": "getCmsCourseInstanceOrganizationId", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Organization id", "content": { "text/plain": { "schema": { "type": "string", "format": "uuid" } } } } } } }, "/api/v0/cms/courses/{course_id}": { "get": { "tags": ["cms_courses"], "summary": "\nGET /api/v0/cms/courses/:course_id - Get the course.", "operationId": "getCmsCourse", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Course" } } } } } } }, "/api/v0/cms/courses/{course_id}/course-instances": { "get": { "tags": ["cms_courses"], "summary": "\nGET `/api/v0/cms/courses/:course_id/course-instances` - Returns all course instances for given course id.", "operationId": "getCmsCourseInstances", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course instances", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CourseInstance" } } } } } } } }, "/api/v0/cms/courses/{course_id}/default-peer-review": { "get": { "tags": ["cms_courses"], "operationId": "getCmsCourseDefaultPeerReview", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Default peer review configuration", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CmsPeerOrSelfReviewConfiguration" } } } } } }, "put": { "tags": ["cms_courses"], "operationId": "updateCmsCourseDefaultPeerReview", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CmsPeerOrSelfReviewConfiguration" } } }, "required": true }, "responses": { "200": { "description": "Updated default peer review configuration", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CmsPeerOrSelfReviewConfiguration" } } } } } } }, "/api/v0/cms/courses/{course_id}/modules": { "get": { "tags": ["cms_courses"], "summary": "\nGET `/api/v0/cms/courses/:course_id/modules`\nReturns modules in the course.", "operationId": "getCmsCourseModules", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course modules", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CourseModule" } } } } } } } }, "/api/v0/cms/courses/{course_id}/nondefault-chatbot-configurations": { "get": { "tags": ["cms_courses"], "summary": "\nGET /api/v0/cms/courses/:course_id/nondefault-chatbot-configurations - Get all nondefault, enabled-to-students chatbot configurations of this course.", "operationId": "getCmsCourseNondefaultChatbotConfigurations", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Chatbot configurations", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ChatbotConfiguration" } } } } } } } }, "/api/v0/cms/courses/{course_id}/pages": { "get": { "tags": ["cms_courses"], "summary": "\nGET `/api/v0/cms/courses/:course_id/pages` - Gets all pages for a course.", "operationId": "getCmsCoursePages", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Pages for course", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Page" } } } } } } } }, "/api/v0/cms/courses/{course_id}/partners-block": { "get": { "tags": ["cms_courses"], "summary": "\nGET /courses/:course_id/partners_blocks - Gets a partners block related to a course", "operationId": "getCmsCoursePartnersBlock", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Partners block", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PartnersBlock" } } } } } }, "post": { "tags": ["cms_courses"], "summary": "\n POST /api/v0/main-frontend/courses/:course_id/partners_block - Create or updates a partners block for a course", "operationId": "upsertCmsCoursePartnersBlock", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": {} } } }, "responses": { "200": { "description": "Partners block upserted" } } }, "delete": { "tags": ["cms_courses"], "summary": "\nDELETE `/api/v0/main-frontend/courses/:course_id` - Delete a partners block in a course.", "operationId": "deleteCmsCoursePartnersBlock", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted partners block", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PartnersBlock" } } } } } } }, "/api/v0/cms/courses/{course_id}/research-consent-form": { "get": { "tags": ["cms_courses"], "summary": "\nGET `/api/v0/cms/courses/:course_id/research-consent-form` - Fetches courses research form with course id.", "operationId": "getCmsCourseResearchForm", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Research form", "content": { "application/json": { "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ResearchForm" } ] } } } } } }, "put": { "tags": ["cms_courses"], "summary": "\nPUT `/api/v0/cms/courses/:course_id/research-consent-form` - Upserts courses research form from Gutenberg research form edit.", "operationId": "upsertCmsCourseResearchForm", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewResearchForm" } } }, "required": true }, "responses": { "200": { "description": "Research form", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResearchForm" } } } } } } }, "/api/v0/cms/courses/{course_id}/research-consent-form-questions": { "put": { "tags": ["cms_courses"], "summary": "\nPUT `/api/v0/cms/courses/:course_id/research-consent-form-questions` - Upserts questions for the courses research form from Gutenberg research form edit.", "operationId": "upsertCmsCourseResearchFormQuestions", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/NewResearchFormQuestion" } } } }, "required": true }, "responses": { "200": { "description": "Research form questions", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ResearchFormQuestion" } } } } } } } }, "/api/v0/cms/courses/{course_id}/upload": { "post": { "tags": ["cms_courses"], "summary": "\nPOST `/api/v0/cms/courses/:course_id/upload` - Uploads a media (image, audio, file) for the course from Gutenberg page edit.\n\nPut the the contents of the media in a form and add a content type header multipart/form-data.\n# Example\n\nRequest:\n```http\nPOST /api/v0/cms/pages/d86cf910-4d26-40e9-8c9c-1cc35294fdbb/upload HTTP/1.1\nContent-Type: multipart/form-data\n\nBINARY_DATA\n```", "operationId": "uploadCmsCourseMedia", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "string" } } }, "required": true }, "responses": { "200": { "description": "Uploaded media result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UploadResult" } } } } } } }, "/api/v0/cms/email-templates/{email_template_id}": { "get": { "tags": ["cms_email_templates"], "summary": "\nGET `/api/v0/cms/email-templates/:id`", "operationId": "getCmsEmailTemplate", "parameters": [ { "name": "email_template_id", "in": "path", "description": "Email template id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Email template", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailTemplate" } } } } } }, "put": { "tags": ["cms_email_templates"], "summary": "\nPUT `/api/v0/cms/email-templates/:id", "operationId": "updateCmsEmailTemplate", "parameters": [ { "name": "email_template_id", "in": "path", "description": "Email template id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailTemplateUpdate" } } }, "required": true }, "responses": { "200": { "description": "Updated email template", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailTemplate" } } } } } }, "delete": { "tags": ["cms_email_templates"], "summary": "\nDELETE `/api/v0/cms/email-templates/:id`", "operationId": "deleteCmsEmailTemplate", "parameters": [ { "name": "email_template_id", "in": "path", "description": "Email template id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted email template", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailTemplate" } } } } } } }, "/api/v0/cms/exams/{exam_id}/edit": { "get": { "tags": ["cms_exams"], "summary": "\nGET `/api/v0/cms/exams/:exam_id/edit` - Get the exam instructions for Gutenberg Editor.", "operationId": "getCmsExamInstructions", "parameters": [ { "name": "exam_id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exam instructions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExamInstructions" } } } } } }, "put": { "tags": ["cms_exams"], "summary": "\nPUT `/api/v0/cms/exams/:exam_id/edit` - Insert new instructions from Gutenberg editor.\n\n# Example\n\nRequest:\n```http\nPUT /api/v0/cms/exams/d86cf910-4d26-40e9-8c9c-1cc35294fdbb/edit HTTP/1.1\n```", "operationId": "updateCmsExamInstructions", "parameters": [ { "name": "exam_id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExamInstructionsUpdate" } } }, "required": true }, "responses": { "200": { "description": "Updated exam instructions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExamInstructions" } } } } } } }, "/api/v0/cms/exams/{exam_id}/upload": { "post": { "tags": ["cms_exams"], "summary": "\nPOST `/api/v0/cms/exams/:exam_id/upload` - Uploads a media (image, audio, file) for the course from Gutenberg page edit.\n\nPut the the contents of the media in a form and add a content type header multipart/form-data.\n# Example\n\nRequest:\n```http\nPOST /api/v0/cms/pages/d86cf910-4d26-40e9-8c9c-1cc35294fdbb/upload HTTP/1.1\nContent-Type: multipart/form-data\n\nBINARY_DATA\n```", "operationId": "uploadCmsExamMedia", "parameters": [ { "name": "exam_id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "string" } } }, "required": true }, "responses": { "200": { "description": "Uploaded media result", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UploadResult" } } } } } } }, "/api/v0/cms/exercise-services": { "get": { "tags": ["cms_exercise_services"], "summary": "\nGET `/api/v0/cms/exercise-services` - List all exercise services configured in the system.", "operationId": "getCmsExerciseServices", "responses": { "200": { "description": "Exercise services", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseServiceIframeRenderingInfo" } } } } } } } }, "/api/v0/cms/pages/{page_id}": { "get": { "tags": ["cms_pages"], "summary": "\nGET `/api/v0/cms/pages/:page_id` - Get a page with exercises and exercise tasks by id.\n\nRequest: `GET /api/v0/cms/pages/40ca9bcf-8eaa-41ba-940e-0fd5dd0c3c02`", "operationId": "getCmsPage", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "CMS page with exercises and peer review data", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContentManagementPage" } } } } } }, "put": { "tags": ["cms_pages"], "summary": "\nPUT `/api/v0/cms/pages/:page_id` - Update a page by id.\n\nPlease note that this endpoint will change all the exercise and exercise task ids you've created. Make sure the use the updated ids from the response object.\n\nIf optional property front_page_of_chapter_id is set, this page will become the front page of the specified course part.\n\n# Example: OUTDATED\n\nRequest:\n\n```http\nPUT /api/v0/cms/pages/40ca9bcf-8eaa-41ba-940e-0fd5dd0c3c02 HTTP/1.1\nContent-Type: application/json\n\n{\n \"content\": [{\"type\": \"x\"}],\n \"url_path\": \"/part-1/hello-world\",\n \"title\": \"Hello world!\",\n \"chapter_id\": \"2495ffa3-7ea9-4615-baa5-828023688c79\"\n}\n```", "operationId": "updateCmsPage", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CmsPageUpdate" } } }, "required": true }, "responses": { "200": { "description": "Updated CMS page", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ContentManagementPage" } } } } } } }, "/api/v0/cms/pages/{page_id}/exercises-with-submissions": { "post": { "tags": ["cms_pages"], "summary": "\nPOST `/api/v0/cms/pages/:page_id/exercises-with-submissions` - Given a set of exercise ids, returns\nthe subset that has at least one existing submission. Used by the editor to warn the teacher before\nsaving a page edit that would remove one of these exercises, since that soft-deletes it and orphans\nits submissions.", "operationId": "getExercisesWithSubmissions", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "type": "array", "items": { "type": "string", "format": "uuid" } } } }, "required": true }, "responses": { "200": { "description": "Exercise ids, among the given ones, that have submissions", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "string", "format": "uuid" } } } } } } } }, "/api/v0/cms/pages/{page_id}/info": { "get": { "tags": ["cms_pages"], "summary": "\nGET `/api/v0/cms/pages/:page_id/info` - Get a pages's course id, course name, organization slug\n\nRequest: `GET /api/v0/cms/pages/40ca9bcf-8eaa-41ba-940e-0fd5dd0c3c02/info`", "operationId": "getCmsPageInfo", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Page info", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PageInfo" } } } } } } }, "/api/v0/cms/pages/{page_id}/page-navigation": { "get": { "tags": ["cms_pages"], "summary": "\nGET /api/v0/cms/pages/:page_id/page-navigation - tells what's the next page, previous page, and the chapter front page given a page id.", "operationId": "getCmsPageNavigation", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Page navigation", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PageNavigationInformation" } } } } } } }, "/api/v0/cms/repository-exercises/{course_id}": { "get": { "tags": ["cms_repository_exercises"], "operationId": "getCmsRepositoryExercisesForCourse", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Repository exercises for course", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/RepositoryExercise" } } } } } } } }, "/api/v0/files/{exercise_service_slug}": { "post": { "tags": ["files"], "summary": "\nPOST `/api/v0/files/:exercise_service_slug`\nUsed to upload data from exercise service iframes.\n\n# Returns\nAn ordered list of host-assigned file ids and stored URLs.", "operationId": "uploadFilesFromExerciseService", "parameters": [ { "name": "exercise_service_slug", "in": "path", "description": "Exercise service slug", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "additionalProperties": { "type": "string", "format": "binary" }, "propertyNames": { "type": "string" } } } }, "required": true }, "responses": { "200": { "description": "Uploaded files", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseServiceUploadResultEntry" } } } } } } } } }, "components": { "schemas": { "AutomaticCompletionRequirements": { "type": "object", "required": ["course_module_id", "requires_exam"], "properties": { "course_module_id": { "type": "string", "format": "uuid", "description": "Course module associated with these requirements." }, "number_of_exercises_attempted_treshold": { "type": ["integer", "null"], "format": "int32" }, "number_of_points_treshold": { "type": ["integer", "null"], "format": "int32" }, "requires_exam": { "type": "boolean" } } }, "ChatbotConfiguration": { "type": "object", "required": [ "id", "created_at", "updated_at", "enabled_to_students", "chatbot_name", "model_id", "prompt", "initial_message", "weekly_tokens_per_user", "daily_tokens_per_user", "temperature", "top_p", "frequency_penalty", "presence_penalty", "max_output_tokens", "verbosity", "reasoning_effort", "use_azure_search", "maintain_azure_search_index", "hide_citations", "use_semantic_reranking", "enabled_tool_categories", "default_chatbot", "suggest_next_messages", "publicly_accessible" ], "properties": { "chatbot_name": { "type": "string" }, "course_id": { "type": ["string", "null"], "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "daily_tokens_per_user": { "type": "integer", "format": "int32" }, "default_chatbot": { "type": "boolean" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "enabled_to_students": { "type": "boolean" }, "enabled_tool_categories": { "type": "array", "items": { "$ref": "#/components/schemas/ToolCategory" } }, "frequency_penalty": { "type": "number", "format": "float" }, "hide_citations": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "initial_message": { "type": "string" }, "initial_suggested_messages": { "type": ["array", "null"], "items": { "type": "string" } }, "maintain_azure_search_index": { "type": "boolean" }, "max_output_tokens": { "type": "integer", "format": "int32" }, "model_id": { "type": "string", "format": "uuid" }, "presence_penalty": { "type": "number", "format": "float" }, "prompt": { "type": "string" }, "publicly_accessible": { "type": "boolean" }, "reasoning_effort": { "$ref": "#/components/schemas/ReasoningEffortLevel" }, "suggest_next_messages": { "type": "boolean" }, "temperature": { "type": "number", "format": "float" }, "top_p": { "type": "number", "format": "float" }, "updated_at": { "type": "string", "format": "date-time" }, "use_azure_search": { "type": "boolean" }, "use_semantic_reranking": { "type": "boolean" }, "verbosity": { "$ref": "#/components/schemas/VerbosityLevel" }, "weekly_tokens_per_user": { "type": "integer", "format": "int32" } } }, "CmsPageExercise": { "type": "object", "required": [ "id", "name", "order_number", "score_maximum", "limit_number_of_tries", "needs_peer_review", "needs_self_review", "use_course_default_peer_or_self_review_config", "teacher_reviews_answer_after_locking" ], "properties": { "deadline": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "limit_number_of_tries": { "type": "boolean" }, "max_tries_per_slide": { "type": ["integer", "null"], "format": "int32" }, "name": { "type": "string" }, "needs_peer_review": { "type": "boolean" }, "needs_self_review": { "type": "boolean" }, "order_number": { "type": "integer", "format": "int32" }, "peer_or_self_review_config": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CmsPeerOrSelfReviewConfig" } ] }, "peer_or_self_review_questions": { "type": ["array", "null"], "items": { "$ref": "#/components/schemas/CmsPeerOrSelfReviewQuestion" } }, "score_maximum": { "type": "integer", "format": "int32" }, "teacher_reviews_answer_after_locking": { "type": "boolean" }, "use_course_default_peer_or_self_review_config": { "type": "boolean" } } }, "CmsPageExerciseSlide": { "type": "object", "required": ["id", "exercise_id", "order_number"], "properties": { "exercise_id": { "type": "string", "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "order_number": { "type": "integer", "format": "int32" } } }, "CmsPageExerciseTask": { "type": "object", "required": ["id", "exercise_slide_id", "assignment", "exercise_type", "order_number"], "properties": { "assignment": {}, "exercise_slide_id": { "type": "string", "format": "uuid" }, "exercise_type": { "type": "string" }, "id": { "type": "string", "format": "uuid" }, "order_number": { "type": "integer", "format": "int32" }, "private_spec": {}, "private_spec_files": { "type": "array", "items": { "type": "string", "format": "uuid" }, "description": "The stored files this task's private spec references, as the exercise service declared them\nin the editor. The host cannot read the spec, so this list is the only thing keeping the\nfiles from being reclaimed as abandoned uploads — and the CMS round-trips it through a block\nattribute, so a load that leaves it empty makes the next save drop the references.\n\nOnly the private spec's. Each derived spec declares its own files in the response of the\nendpoint that produced it, since a derivation may upload files of its own." } } }, "CmsPageUpdate": { "type": "object", "required": [ "content", "exercises", "exercise_slides", "exercise_tasks", "url_path", "title", "hidden" ], "properties": { "chapter_id": { "type": ["string", "null"], "format": "uuid" }, "content": { "type": "array", "items": { "$ref": "#/components/schemas/GutenbergBlock" } }, "exercise_slides": { "type": "array", "items": { "$ref": "#/components/schemas/CmsPageExerciseSlide" } }, "exercise_tasks": { "type": "array", "items": { "$ref": "#/components/schemas/CmsPageExerciseTask" } }, "exercises": { "type": "array", "items": { "$ref": "#/components/schemas/CmsPageExercise" } }, "hidden": { "type": "boolean" }, "title": { "type": "string" }, "url_path": { "type": "string" } } }, "CmsPeerOrSelfReviewConfig": { "type": "object", "required": [ "id", "course_id", "peer_reviews_to_give", "peer_reviews_to_receive", "accepting_threshold", "processing_strategy", "points_are_all_or_nothing", "reset_answer_if_zero_points_from_review" ], "properties": { "accepting_threshold": { "type": "number", "format": "float" }, "course_id": { "type": "string", "format": "uuid" }, "exercise_id": { "type": ["string", "null"], "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "peer_reviews_to_give": { "type": "integer", "format": "int32" }, "peer_reviews_to_receive": { "type": "integer", "format": "int32" }, "points_are_all_or_nothing": { "type": "boolean" }, "processing_strategy": { "$ref": "#/components/schemas/PeerReviewProcessingStrategy" }, "reset_answer_if_zero_points_from_review": { "type": "boolean" }, "review_instructions": {} } }, "CmsPeerOrSelfReviewConfiguration": { "type": "object", "required": ["peer_or_self_review_config", "peer_or_self_review_questions"], "properties": { "peer_or_self_review_config": { "$ref": "#/components/schemas/CmsPeerOrSelfReviewConfig" }, "peer_or_self_review_questions": { "type": "array", "items": { "$ref": "#/components/schemas/CmsPeerOrSelfReviewQuestion" } } } }, "CmsPeerOrSelfReviewQuestion": { "type": "object", "required": [ "id", "peer_or_self_review_config_id", "order_number", "question", "question_type", "answer_required", "weight" ], "properties": { "answer_required": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "order_number": { "type": "integer", "format": "int32" }, "peer_or_self_review_config_id": { "type": "string", "format": "uuid" }, "question": { "type": "string" }, "question_type": { "$ref": "#/components/schemas/PeerOrSelfReviewQuestionType" }, "weight": { "type": "number", "format": "float" } } }, "CodeGiveaway": { "type": "object", "required": ["id", "created_at", "updated_at", "course_id", "enabled", "name"], "properties": { "course_id": { "type": "string", "format": "uuid" }, "course_module_id": { "type": ["string", "null"], "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "enabled": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "require_course_specific_consent_form_question_id": { "type": ["string", "null"], "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" } } }, "CompletionPolicy": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/AutomaticCompletionRequirements" }, { "type": "object", "required": ["policy"], "properties": { "policy": { "type": "string", "enum": ["automatic"] } } } ] }, { "type": "object", "required": ["policy"], "properties": { "policy": { "type": "string", "enum": ["manual"] } } } ] }, "ContentManagementPage": { "type": "object", "required": [ "page", "exercises", "exercise_slides", "exercise_tasks", "peer_or_self_review_configs", "peer_or_self_review_questions", "organization_id" ], "properties": { "exercise_slides": { "type": "array", "items": { "$ref": "#/components/schemas/CmsPageExerciseSlide" } }, "exercise_tasks": { "type": "array", "items": { "$ref": "#/components/schemas/CmsPageExerciseTask" } }, "exercises": { "type": "array", "items": { "$ref": "#/components/schemas/CmsPageExercise" } }, "organization_id": { "type": "string", "format": "uuid" }, "page": { "$ref": "#/components/schemas/Page" }, "peer_or_self_review_configs": { "type": "array", "items": { "$ref": "#/components/schemas/CmsPeerOrSelfReviewConfig" } }, "peer_or_self_review_questions": { "type": "array", "items": { "$ref": "#/components/schemas/CmsPeerOrSelfReviewQuestion" } } } }, "Course": { "type": "object", "required": [ "id", "slug", "created_at", "updated_at", "name", "organization_id", "language_code", "course_language_group_id", "is_draft", "is_test_mode", "is_unlisted", "base_module_completion_requires_n_submodule_completions", "can_add_chatbot", "is_joinable_by_code_only", "ask_marketing_consent", "flagged_answers_skip_manual_review_and_allow_retry", "chapter_locking_enabled", "cheater_detection_enabled", "ai_policy" ], "properties": { "ai_policy": { "$ref": "#/components/schemas/CourseAiPolicy" }, "ask_marketing_consent": { "type": "boolean" }, "base_module_completion_requires_n_submodule_completions": { "type": "integer", "format": "int32" }, "can_add_chatbot": { "type": "boolean" }, "chapter_locking_enabled": { "type": "boolean" }, "cheater_detection_enabled": { "type": "boolean" }, "closed_additional_message": { "type": ["string", "null"] }, "closed_at": { "type": ["string", "null"], "format": "date-time" }, "closed_course_successor_id": { "type": ["string", "null"], "format": "uuid" }, "content_search_language": { "type": ["string", "null"] }, "copied_from": { "type": ["string", "null"], "format": "uuid" }, "course_language_group_id": { "type": "string", "format": "uuid" }, "course_material_ai_instructions": { "type": ["boolean", "null"] }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "description": { "type": ["string", "null"] }, "flagged_answers_skip_manual_review_and_allow_retry": { "type": "boolean" }, "flagged_answers_threshold": { "type": ["integer", "null"], "format": "int32" }, "id": { "type": "string", "format": "uuid" }, "is_draft": { "type": "boolean" }, "is_joinable_by_code_only": { "type": "boolean" }, "is_test_mode": { "type": "boolean" }, "is_unlisted": { "type": "boolean" }, "join_code": { "type": ["string", "null"] }, "language_code": { "type": "string" }, "name": { "type": "string" }, "organization_id": { "type": "string", "format": "uuid" }, "slug": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "CourseAiPolicy": { "type": "string", "description": "The AI policy a teacher has selected for a course. Drives which variant of the student-facing\nAI usage notice is shown; `NotSet` (the default) keeps the generic default message.", "enum": ["NotSet", "NoAi", "PlanningOnly", "Limited", "FullUse", "Required"] }, "CourseInstance": { "type": "object", "required": [ "id", "created_at", "updated_at", "course_id", "teacher_in_charge_name", "teacher_in_charge_email" ], "properties": { "course_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "description": { "type": ["string", "null"] }, "ends_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": ["string", "null"] }, "starts_at": { "type": ["string", "null"], "format": "date-time" }, "support_email": { "type": ["string", "null"] }, "teacher_in_charge_email": { "type": "string" }, "teacher_in_charge_name": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "CourseModule": { "type": "object", "description": "Like [CourseModulesSchema], but the automatic-completion columns are collapsed into\n`completion_policy`.", "required": [ "id", "created_at", "updated_at", "course_id", "order_number", "completion_policy", "enable_registering_completion_to_uh_open_university", "certification_enabled", "enable_credit_registration_via_suotar" ], "properties": { "certification_enabled": { "type": "boolean" }, "completion_policy": { "$ref": "#/components/schemas/CompletionPolicy" }, "completion_registration_link_override": { "type": ["string", "null"], "description": "If set, use this link rather than the default one when registering course completions." }, "copied_from": { "type": ["string", "null"], "format": "uuid" }, "course_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "ects_credits": { "type": ["number", "null"], "format": "float" }, "enable_credit_registration_via_suotar": { "type": "boolean" }, "enable_registering_completion_to_uh_open_university": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": ["string", "null"] }, "order_number": { "type": "integer", "format": "int32" }, "uh_course_code": { "type": ["string", "null"] }, "updated_at": { "type": "string", "format": "date-time" } } }, "DatabaseChapter": { "type": "object", "required": [ "id", "created_at", "updated_at", "name", "course_id", "chapter_number", "course_module_id" ], "properties": { "chapter_image_path": { "type": ["string", "null"] }, "chapter_number": { "type": "integer", "format": "int32" }, "color": { "type": ["string", "null"] }, "copied_from": { "type": ["string", "null"], "format": "uuid" }, "course_id": { "type": "string", "format": "uuid" }, "course_module_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deadline": { "type": ["string", "null"], "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "front_page_id": { "type": ["string", "null"], "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "opens_at": { "type": ["string", "null"], "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" } } }, "EmailTemplate": { "type": "object", "required": ["id", "created_at", "updated_at", "template_type"], "properties": { "content": {}, "course_id": { "type": ["string", "null"], "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "exercise_completions_threshold": { "type": ["integer", "null"], "format": "int32" }, "id": { "type": "string", "format": "uuid" }, "language": { "type": ["string", "null"] }, "points_threshold": { "type": ["integer", "null"], "format": "int32" }, "subject": { "type": ["string", "null"] }, "template_type": { "$ref": "#/components/schemas/EmailTemplateType" }, "updated_at": { "type": "string", "format": "date-time" } } }, "EmailTemplateType": { "type": "string", "enum": [ "reset_password_email", "delete_user_email", "confirm_email_code", "generic", "credit_registration_account_linking", "verify_email_address", "credit_registration_action_needed", "credit_registration_registered", "credit_registration_student_number_linked" ] }, "EmailTemplateUpdate": { "type": "object", "required": ["template_type", "subject", "content"], "properties": { "content": {}, "exercise_completions_threshold": { "type": ["integer", "null"], "format": "int32" }, "points_threshold": { "type": ["integer", "null"], "format": "int32" }, "subject": { "type": "string" }, "template_type": { "$ref": "#/components/schemas/EmailTemplateType" } } }, "ExamInstructions": { "type": "object", "required": ["id", "instructions"], "properties": { "id": { "type": "string", "format": "uuid" }, "instructions": {} } }, "ExamInstructionsUpdate": { "type": "object", "required": ["instructions"], "properties": { "instructions": {} } }, "ExerciseServiceIframeRenderingInfo": { "type": "object", "description": "Exercise service definition that the CMS can use to render the editor view.", "required": ["id", "name", "slug", "public_iframe_url", "has_custom_view"], "properties": { "has_custom_view": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "public_iframe_url": { "type": "string" }, "slug": { "type": "string" } } }, "ExerciseServiceUploadResultEntry": { "type": "object", "description": "What an upload route returns for one stored file: the `file_uploads` row id an answer names it\nby, and the URL it can be fetched from.", "required": ["id", "url"], "properties": { "id": { "type": "string", "format": "uuid" }, "url": { "type": "string" } } }, "GutenbergBlock": { "type": "object", "required": ["clientId", "name", "isValid", "attributes", "innerBlocks"], "properties": { "attributes": { "type": "object", "additionalProperties": {}, "propertyNames": { "type": "string" } }, "clientId": { "type": "string", "format": "uuid" }, "innerBlocks": { "type": "array", "items": { "$ref": "#/components/schemas/GutenbergBlock" } }, "isValid": { "type": "boolean" }, "name": { "type": "string" } } }, "NewResearchForm": { "type": "object", "required": ["course_id", "content"], "properties": { "content": {}, "course_id": { "type": "string", "format": "uuid" } } }, "NewResearchFormQuestion": { "type": "object", "required": ["question_id", "course_id", "research_consent_form_id", "question"], "properties": { "course_id": { "type": "string", "format": "uuid" }, "question": { "type": "string" }, "question_id": { "type": "string", "format": "uuid" }, "research_consent_form_id": { "type": "string", "format": "uuid" } } }, "Page": { "type": "object", "required": [ "id", "created_at", "updated_at", "url_path", "title", "content", "order_number", "hidden" ], "properties": { "chapter_id": { "type": ["string", "null"], "format": "uuid" }, "content": {}, "copied_from": { "type": ["string", "null"], "format": "uuid" }, "course_id": { "type": ["string", "null"], "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "exam_id": { "type": ["string", "null"], "format": "uuid" }, "hidden": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "order_number": { "type": "integer", "format": "int32" }, "page_language_group_id": { "type": ["string", "null"], "format": "uuid" }, "title": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" }, "url_path": { "type": "string" } } }, "PageInfo": { "type": "object", "required": ["page_id", "page_title"], "properties": { "course_id": { "type": ["string", "null"], "format": "uuid" }, "course_name": { "type": ["string", "null"] }, "course_slug": { "type": ["string", "null"] }, "organization_slug": { "type": ["string", "null"] }, "page_id": { "type": "string", "format": "uuid" }, "page_title": { "type": "string" } } }, "PageNavigationInformation": { "type": "object", "properties": { "chapter_front_page": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PageRoutingData" } ] }, "next_page": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PageRoutingData" } ] }, "previous_page": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PageRoutingData" } ] } } }, "PageRoutingData": { "type": "object", "required": ["url_path", "title", "page_id", "chapter_number", "chapter_id"], "properties": { "chapter_front_page_id": { "type": ["string", "null"], "format": "uuid" }, "chapter_id": { "type": "string", "format": "uuid" }, "chapter_number": { "type": "integer", "format": "int32" }, "chapter_opens_at": { "type": ["string", "null"], "format": "date-time" }, "page_id": { "type": "string", "format": "uuid" }, "title": { "type": "string" }, "url_path": { "type": "string" } } }, "ParagraphSuggestionAction": { "type": "string", "enum": [ "moocfi/ai/generate-draft-from-notes", "moocfi/ai/generate-continue-paragraph", "moocfi/ai/generate-add-example", "moocfi/ai/generate-add-counterpoint", "moocfi/ai/generate-add-concluding-sentence", "moocfi/fix-spelling", "moocfi/ai/improve-clarity", "moocfi/ai/improve-flow", "moocfi/ai/improve-concise", "moocfi/ai/improve-expand-detail", "moocfi/ai/improve-academic-style", "moocfi/ai/structure-create-topic-sentence", "moocfi/ai/structure-reorder-sentences", "moocfi/ai/structure-split-into-paragraphs", "moocfi/ai/structure-combine-into-one", "moocfi/ai/structure-to-bullets", "moocfi/ai/structure-from-bullets", "moocfi/ai/learning-simplify-beginners", "moocfi/ai/learning-add-definitions", "moocfi/ai/learning-add-analogy", "moocfi/ai/learning-add-practice-question", "moocfi/ai/learning-add-check-understanding", "moocfi/ai/summaries-one-sentence", "moocfi/ai/summaries-two-three-sentences", "moocfi/ai/summaries-key-takeaway", "moocfi/ai/tone-academic-formal", "moocfi/ai/tone-friendly-conversational", "moocfi/ai/tone-encouraging-supportive", "moocfi/ai/tone-neutral-objective", "moocfi/ai/tone-confident", "moocfi/ai/tone-serious", "moocfi/ai/translate-english", "moocfi/ai/translate-finnish", "moocfi/ai/translate-norwegian", "moocfi/ai/translate-swedish" ] }, "ParagraphSuggestionContext": { "type": "object", "properties": { "course_id": { "type": ["string", "null"], "format": "uuid" }, "locale": { "type": ["string", "null"] }, "page_id": { "type": ["string", "null"], "format": "uuid" } } }, "ParagraphSuggestionMeta": { "type": "object", "properties": { "language": { "type": ["string", "null"] }, "setting_type": { "type": ["string", "null"] }, "tone": { "type": ["string", "null"] } } }, "ParagraphSuggestionRequest": { "type": "object", "required": ["action", "content", "is_html"], "properties": { "action": { "$ref": "#/components/schemas/ParagraphSuggestionAction" }, "content": { "type": "string" }, "context": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ParagraphSuggestionContext" } ] }, "is_html": { "type": "boolean" }, "meta": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ParagraphSuggestionMeta" } ] } } }, "ParagraphSuggestionResponse": { "type": "object", "required": ["suggestions"], "properties": { "suggestions": { "type": "array", "items": { "type": "string" } } } }, "PartnersBlock": { "type": "object", "required": ["id", "created_at", "updated_at", "content", "course_id"], "properties": { "content": {}, "course_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" } } }, "PeerOrSelfReviewQuestionType": { "type": "string", "enum": ["Essay", "Scale"] }, "PeerReviewProcessingStrategy": { "type": "string", "description": "\nDetermines how we will treat the answer being peer reviewed once it has received enough reviews and the student has given enough peer reviews.\n\nSome strategies compare the overall received peer review likert answer (1-5) average to peer_reviews.accepting threshold.", "enum": [ "AutomaticallyGradeByAverage", "AutomaticallyGradeOrManualReviewByAverage", "ManualReviewEverything" ] }, "ReasoningEffortLevel": { "type": "string", "enum": ["none", "minimal", "low", "medium", "high", "xhigh"] }, "RepositoryExercise": { "type": "object", "required": [ "id", "repository_id", "part", "name", "repository_url", "checksum", "download_url" ], "properties": { "checksum": { "type": "array", "items": { "type": "integer", "format": "int32", "minimum": 0 } }, "download_url": { "type": "string" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "part": { "type": "string" }, "repository_id": { "type": "string", "format": "uuid" }, "repository_url": { "type": "string" } } }, "ResearchForm": { "type": "object", "required": ["id", "course_id", "content", "created_at", "updated_at"], "properties": { "content": {}, "course_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ResearchFormQuestion": { "type": "object", "required": [ "id", "course_id", "research_consent_form_id", "question", "created_at", "updated_at" ], "properties": { "course_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "question": { "type": "string" }, "research_consent_form_id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ToolCategory": { "type": "string", "description": "A category of chatbot tools a configuration can choose to offer the LLM. Independent of the\nchatbot crate's per-tool `ToolPermission` check: a category answers \"does this chatbot offer\nthis kind of tool\", not \"may this caller use it\".", "enum": [ "course_material", "course_info", "course_catalog", "interaction", "admin_support_accounts", "admin_support_courses", "admin_support_learning_progress", "admin_support_academic_integrity" ] }, "UploadResult": { "type": "object", "description": "Result of a image upload. Tells where the uploaded image can be retrieved from.", "required": ["url"], "properties": { "url": { "type": "string" } } }, "VerbosityLevel": { "type": "string", "enum": ["low", "medium", "high"] } } } }