{ "openapi": "3.1.0", "info": { "title": "Main Frontend 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/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\nThe randomly generated paths to each uploaded file in a `file_name => file_path` hash map.", "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": "string" } } }, "required": true }, "responses": { "200": { "description": "Uploaded files", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } } } } } } } }, "/api/v0/main-frontend/certificates": { "post": { "tags": ["certificates"], "summary": "\nPOST `/api/v0/main-frontend/certificates/`\n\nUpdates the certificate configuration for a given module.", "operationId": "updateCertificateConfiguration", "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "required": ["metadata", "file"], "properties": { "file": { "type": "array", "items": { "type": "string", "format": "binary" }, "contentMediaType": "application/octet-stream" }, "metadata": { "$ref": "#/components/schemas/CertificateConfigurationUpdate" } } }, "encoding": { "metadata": { "contentType": "application/json" } } } }, "required": true }, "responses": { "200": { "description": "Certificate configuration updated", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/certificates/configuration/{certificate_configuration_id}": { "delete": { "tags": ["certificates"], "summary": "\nDELETE `/api/v0/main-frontend/certificates/configuration/{configuration_id}`\n\nDeletes the given configuration.", "operationId": "deleteCertificateConfiguration", "parameters": [ { "name": "certificate_configuration_id", "in": "path", "description": "Certificate configuration id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Certificate configuration deleted", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/certificates/generate": { "post": { "tags": ["certificates"], "summary": "\nPOST `/api/v0/main-frontend/certificates/generate`\n\nGenerates a certificate for a given certificate configuration id.", "operationId": "generateCertificate", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CertificateGenerationRequest" } } }, "required": true }, "responses": { "200": { "description": "Certificate generated", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/certificates/generated/{certificate_id}": { "put": { "tags": ["certificates"], "operationId": "updateGeneratedCertificate", "parameters": [ { "name": "certificate_id", "in": "path", "description": "Generated certificate id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CertificateUpdateRequest" } } }, "required": true }, "responses": { "200": { "description": "Generated certificate updated", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/GeneratedCertificate" } } } } } } }, "/api/v0/main-frontend/certificates/get-by-configuration-id/{certificate_configuration_id}": { "get": { "tags": ["certificates"], "summary": "\nGET `/api/v0/main-frontend/certificates/get-by-configuration-id/{certificate_configuration_id}`\n\nFetches the user's certificate for the given course module and course instance.", "operationId": "getCertificateByConfigurationId", "parameters": [ { "name": "certificate_configuration_id", "in": "path", "description": "Certificate configuration id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Generated certificate", "content": { "application/json": { "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/GeneratedCertificate" } ] } } } } } } }, "/api/v0/main-frontend/certificates/{certificate_verification_id}": { "get": { "tags": ["certificates"], "summary": "\nGET `/api/v0/main-frontend/certificates/{certificate_verification_id}`\n\nFetches the user's certificate using the verification id.\n\nResponse: the certificate as a png.", "operationId": "getCertificateByVerificationId", "parameters": [ { "name": "certificate_verification_id", "in": "path", "description": "Certificate verification id", "required": true, "schema": { "type": "string" } }, { "name": "debug", "in": "query", "description": "Whether to render a debug certificate", "required": true, "schema": { "type": "boolean" } }, { "name": "test_certificate_configuration_id", "in": "query", "description": "Certificate configuration id to use for preview rendering", "required": false, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Certificate image", "content": { "image/png": { "schema": {} } } } } } }, "/api/v0/main-frontend/chapters": { "post": { "tags": ["chapters"], "summary": "\nPOST `/api/v0/main-frontend/chapters` - Create a new course part.\n# Example\n\nRequest:\n```http\nPOST /api/v0/main-frontend/chapters HTTP/1.1\nContent-Type: application/json\n\n{\n \"name\": \"The Basics\",\n \"course_id\": \"d86cf910-4d26-40e9-8c9c-1cc35294fdbb\",\n \"chapter_number\": 1,\n \"front_page_id\": null\n}\n```", "operationId": "createChapter", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewChapter" } } }, "required": true }, "responses": { "200": { "description": "Created chapter", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Chapter" } } } } } } }, "/api/v0/main-frontend/chapters/{chapter_id}": { "put": { "tags": ["chapters"], "summary": "\nPUT `/api/v0/main-frontend/chapters/:chapter_id` - Update chapter.\n# Example\n\nRequest:\n```http\nPUT /api/v0/main-frontend/chapters/d332f3d9-39a5-4a18-80f4-251727693c37 HTTP/1.1\nContent-Type: application/json\n\n{\n \"name\": \"The Basics\",\n \"chapter_image_url\": null,\n \"chapter_number\": 2,\n \"front_page_id\": \"0ebba931-b027-4154-8274-2afb00d79306\"\n}\n\n```", "operationId": "updateChapter", "parameters": [ { "name": "chapter_id", "in": "path", "description": "Chapter id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChapterUpdate" } } }, "required": true }, "responses": { "200": { "description": "Updated chapter", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Chapter" } } } } } }, "delete": { "tags": ["chapters"], "summary": "\nDELETE `/api/v0/main-frontend/chapters/:chapter_id` - Delete a chapter.", "operationId": "deleteChapter", "parameters": [ { "name": "chapter_id", "in": "path", "description": "Chapter id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted chapter", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Chapter" } } } } } } }, "/api/v0/main-frontend/chapters/{chapter_id}/image": { "put": { "tags": ["chapters"], "summary": "\nPUT `/api/v0/main-frontend/chapters/:chapter_id/image` - Sets or updates the chapter image.\n\n# Example\n\nRequest:\n```http\nPUT /api/v0/main-frontend/chapters/d332f3d9-39a5-4a18-80f4-251727693c37/image HTTP/1.1\nContent-Type: multipart/form-data\n\nBINARY_DATA\n```", "operationId": "updateChapterImage", "parameters": [ { "name": "chapter_id", "in": "path", "description": "Chapter id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "required": ["file"], "properties": { "file": { "type": "array", "items": { "type": "integer", "format": "int32", "minimum": 0 }, "contentMediaType": "application/octet-stream" } } } } }, "required": true }, "responses": { "200": { "description": "Updated chapter image", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Chapter" } } } } } }, "delete": { "tags": ["chapters"], "summary": "\nDELETE `/api/v0/main-frontend/chapters/:chapter_id/image` - Removes the chapter image.\n\n# Example\n\nRequest:\n```http\nDELETE /api/v0/main-frontend/chapters/d332f3d9-39a5-4a18-80f4-251727693c37/image HTTP/1.1\n```", "operationId": "deleteChapterImage", "parameters": [ { "name": "chapter_id", "in": "path", "description": "Chapter id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted chapter image" } } } }, "/api/v0/main-frontend/chapters/{course_id}/all-chapters-for-course": { "get": { "tags": ["chapters"], "summary": "\nGET `/api/v0/main-frontend/chapters/{course_id}/all-chapters-for-course - Gets all chapters with a course_id", "operationId": "getCourseChapters", "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/main-frontend/chatbot-models/": { "get": { "tags": ["chatbot-models"], "summary": "GET `/api/v0/main-frontend/chatbot-models?course_id={course_id}`", "operationId": "getChatbotModels", "parameters": [ { "name": "course_id", "in": "query", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Chatbot models", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ChatbotConfigurationModel" } } } } } } } }, "/api/v0/main-frontend/chatbot-models/{chatbot_model_id}": { "get": { "tags": ["chatbot-models"], "summary": "GET `/api/v0/main-frontend/chatbot-models/{chatbot_configuration_id}`", "operationId": "getChatbotModel", "parameters": [ { "name": "chatbot_model_id", "in": "path", "description": "Chatbot model id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "type": "string", "format": "uuid" } } }, "required": true }, "responses": { "200": { "description": "Chatbot model", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatbotConfigurationModel" } } } } } } }, "/api/v0/main-frontend/chatbots/": { "get": { "tags": ["chatbots"], "summary": "GET `/api/v0/main-frontend/chatbots`", "operationId": "getAllChatbots", "responses": { "200": { "description": "All chatbots", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ChatbotConfiguration" } } } } } } } }, "/api/v0/main-frontend/chatbots/{chatbot_configuration_id}": { "get": { "tags": ["chatbots"], "summary": "GET `/api/v0/main-frontend/chatbots/{chatbot_configuration_id}`", "operationId": "getChatbotConfiguration", "parameters": [ { "name": "chatbot_configuration_id", "in": "path", "description": "Chatbot configuration id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Chatbot configuration", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatbotConfiguration" } } } } } }, "post": { "tags": ["chatbots"], "summary": "POST `/api/v0/main-frontend/chatbots/{chatbot_configuration_id}`", "operationId": "configureChatbot", "parameters": [ { "name": "chatbot_configuration_id", "in": "path", "description": "Chatbot configuration id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewChatbotConf" } } }, "required": true }, "responses": { "200": { "description": "Updated chatbot configuration", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatbotConfiguration" } } } } } }, "delete": { "tags": ["chatbots"], "summary": "DELETE `/api/v0/main-frontend/chatbots/{chatbot_configuration_id}`", "operationId": "deleteChatbotConfiguration", "parameters": [ { "name": "chatbot_configuration_id", "in": "path", "description": "Chatbot configuration id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted chatbot configuration" } } } }, "/api/v0/main-frontend/code-giveaways": { "post": { "tags": ["code_giveaways"], "summary": "\n * POST `/api/v0/main-frontend/code-giveaways - Creates a new code giveaway.", "operationId": "createCodeGiveaway", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewCodeGiveaway" } } }, "required": true }, "responses": { "200": { "description": "Created code giveaway", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CodeGiveaway" } } } } } } }, "/api/v0/main-frontend/code-giveaways/by-course/{course_id}": { "get": { "tags": ["code_giveaways"], "summary": "\nGET `/api/v0/main-frontend/code-giveaways/by-course/:course_id` - Returns code giveaways for a course.", "operationId": "getCodeGiveawaysByCourse", "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/main-frontend/code-giveaways/{id}": { "get": { "tags": ["code_giveaways"], "summary": "\n * GET `/api/v0/main-frontend/code-giveaways/:id - Gets a code giveaway by ID.", "operationId": "getCodeGiveawayById", "parameters": [ { "name": "id", "in": "path", "description": "Code giveaway id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Code giveaway", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CodeGiveaway" } } } } } } }, "/api/v0/main-frontend/code-giveaways/{id}/codes": { "get": { "tags": ["code_giveaways"], "summary": "\n * GET `/api/v0/main-frontend/code-giveaways/:id/codes - Gets codes for a code giveaway by ID.", "operationId": "getCodeGiveawayCodes", "parameters": [ { "name": "id", "in": "path", "description": "Code giveaway id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Giveaway codes", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CodeGiveawayCode" } } } } } } }, "post": { "tags": ["code_giveaways"], "summary": "\n * POST `/api/v0/main-frontend/code-giveaways/:id/codes - Adds new codes to a code giveaway.", "operationId": "addCodeGiveawayCodes", "parameters": [ { "name": "id", "in": "path", "description": "Code giveaway id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "type": "array", "items": { "type": "string" } } } }, "required": true }, "responses": { "200": { "description": "Added giveaway codes", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CodeGiveawayCode" } } } } } } } }, "/api/v0/main-frontend/code-giveaways/{id}/codes/csv": { "get": { "tags": ["code_giveaways"], "summary": "\n * GET `/api/v0/main-frontend/code-giveaways/:id/codes/csv - Gets codes for a code giveaway by ID as CSV.", "operationId": "downloadCodeGiveawayCodesCsv", "parameters": [ { "name": "id", "in": "path", "description": "Code giveaway id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Giveaway codes CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/code-giveaways/{id}/codes/{code_id}": { "delete": { "tags": ["code_giveaways"], "summary": "\n * DELETE `/api/v0/main-frontend/code-giveaways/:id/codes/:code_id - Deletes a code giveaway code.", "operationId": "deleteCodeGiveawayCode", "parameters": [ { "name": "id", "in": "path", "description": "Code giveaway id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "code_id", "in": "path", "description": "Giveaway code id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted giveaway code" } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}": { "get": { "tags": ["course-instances"], "summary": "\nGET /course-instances/:id", "operationId": "getCourseInstance", "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/main-frontend/course-instances/{course_instance_id}/completions": { "get": { "tags": ["course-instances"], "summary": "\nGET `/api/v0/main-frontend/course-instances/{course_instance_id}/completions`", "operationId": "getCourseInstanceCompletions", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course instance completion summary", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseInstanceCompletionSummary" } } } } } }, "post": { "tags": ["course-instances"], "summary": "\nPOST `/api/v0/main-frontend/course-instances/{course_instance_id}/completions`", "operationId": "createCourseInstanceCompletions", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TeacherManualCompletionRequest" } } }, "required": true }, "responses": { "200": { "description": "Manual completions added" } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/completions/preview": { "post": { "tags": ["course-instances"], "operationId": "previewCourseInstanceCompletions", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TeacherManualCompletionRequest" } } }, "required": true }, "responses": { "200": { "description": "Manual completion preview", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ManualCompletionPreview" } } } } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/course-module-completions/{user_id}": { "get": { "tags": ["course-instances"], "summary": "\nGET /course-instances/:id/course-module-completions/:user_id - Returns a list of all course module completions for a given user for this course instance.", "operationId": "getCourseInstanceCourseModuleCompletionsForUser", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course module completions for user", "content": { "application/json": { "schema": {} } } } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/default-certificate-configurations": { "get": { "tags": ["course-instances"], "summary": "\nGET /course-instances/:id/default-certificate-configurations - gets default certificate configurations of the given course instance. A default certificate configuration requires only one course module to be completed.", "operationId": "getCourseInstanceDefaultCertificateConfigurations", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Default certificate configurations", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CertificateConfigurationAndRequirements" } } } } } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/delete": { "post": { "tags": ["course-instances"], "summary": "\nPOST /course-instances/:id/delete", "operationId": "deleteCourseInstance", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course instance deleted" } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/edit": { "post": { "tags": ["course-instances"], "summary": "\nPOST /course-instances/:id/edit", "operationId": "editCourseInstance", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseInstanceForm" } } }, "required": true }, "responses": { "200": { "description": "Course instance updated" } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/email-templates": { "get": { "tags": ["course-instances"], "operationId": "getCourseInstanceEmailTemplates", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course instance email templates", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/EmailTemplate" } } } } } } }, "post": { "tags": ["course-instances"], "operationId": "createCourseInstanceEmailTemplate", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailTemplateNew" } } }, "required": true }, "responses": { "200": { "description": "Created email template", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailTemplate" } } } } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/export-completions": { "get": { "tags": ["course-instances"], "summary": "\nGET /course-instances/:id/export-completions - gets CSV of course completion based on course_instance ID.", "operationId": "exportCourseInstanceCompletionsCsv", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course instance completions CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/export-points": { "get": { "tags": ["course-instances"], "summary": "\nGET `/api/v0/main-frontend/course-instances/${courseInstanceId}/export-points` - gets CSV of course instance points based on course_instance ID.", "operationId": "exportCourseInstancePointsCsv", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course instance points CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/points": { "get": { "tags": ["course-instances"], "operationId": "getCourseInstancePoints", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Course instance points", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Points" } } } } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/progress/{user_id}": { "get": { "tags": ["course-instances"], "summary": "\n GET /api/v0/main-frontend/course-instance/:course_instance_id/progress/:user_id - returns user progress information.", "operationId": "getCourseInstanceUserProgress", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User progress for course instance", "content": { "application/json": { "schema": {} } } } } } }, "/api/v0/main-frontend/course-instances/{course_instance_id}/status-for-all-exercises/{user_id}": { "get": { "tags": ["course-instances"], "summary": "\nGET /course-instances/:id/status-for-all-exercises/:user_id - Returns a status for all exercises in a course instance for a given user.", "operationId": "getCourseInstanceExerciseStatusesForUser", "parameters": [ { "name": "course_instance_id", "in": "path", "description": "Course instance id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercise statuses for user", "content": { "application/json": { "schema": {} } } } } } }, "/api/v0/main-frontend/course-modules/{course_module_id}": { "get": { "tags": ["course_modules"], "summary": "\nGET `/api/v0/main-frontend/course-modules/{course_module_id}`\n\nReturns information about the course module.", "operationId": "getCourseModule", "parameters": [ { "name": "course_module_id", "in": "path", "description": "Course module id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course module", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseModule" } } } } } } }, "/api/v0/main-frontend/course-modules/{course_module_id}/completion-registration-link": { "get": { "tags": ["course_modules"], "summary": "\nGET `/api/v0/main-frontend/course-modules/{course_slug}/completion-registration-link`", "operationId": "getCourseModuleCompletionRegistrationLink", "parameters": [ { "name": "course_module_id", "in": "path", "description": "Course module id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Completion registration link", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompletionRegistrationLink" } } } } } } }, "/api/v0/main-frontend/course-modules/{course_module_id}/course-module-completion": { "get": { "tags": ["course_modules"], "summary": "\nGET `/api/v0/main-frontend/course-modules/{course_module_id}/course-module-completion`\n\nGets users's best completion for the course.", "operationId": "getCourseModuleCompletion", "parameters": [ { "name": "course_module_id", "in": "path", "description": "Course module id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Best course module completion for the current user", "content": { "application/json": { "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CourseModuleCompletion" } ] } } } } } } }, "/api/v0/main-frontend/course-modules/{course_module_id}/set-certificate-generation/{enabled}": { "post": { "tags": ["course_modules"], "operationId": "setCourseModuleCertificateGeneration", "parameters": [ { "name": "course_module_id", "in": "path", "description": "Course module id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "enabled", "in": "path", "description": "Whether certificate generation should be enabled", "required": true, "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "Certificate generation updated", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/course-modules/{course_module_id}/threshold": { "post": { "tags": ["course_modules"], "summary": "\n POST /api/v0/main-frontend/course-modules/${course_module_id}/threshold - post threshold for a specific course module.", "operationId": "createCourseModuleThreshold", "parameters": [ { "name": "course_module_id", "in": "path", "description": "Course module id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ThresholdData" } } }, "required": true }, "responses": { "200": { "description": "Threshold created" } } }, "delete": { "tags": ["course_modules"], "summary": "\n DELETE /api/v0/main-frontend/course-modules/${course_module_id}/threshold - delete threshold for a specific course module.", "operationId": "deleteCourseModuleThreshold", "parameters": [ { "name": "course_module_id", "in": "path", "description": "Course module id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Threshold deleted" } } } }, "/api/v0/main-frontend/course-modules/{course_module_id}/user-completion": { "get": { "tags": ["course_modules"], "summary": "\nGET `/api/v0/main-frontend/course-modules/{course_module_id}/user-completion`\n\nGets active users's completion for the course, if it exists.", "operationId": "getCourseModuleUserCompletion", "parameters": [ { "name": "course_module_id", "in": "path", "description": "Course module id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User completion information", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserCompletionInformation" } } } } } } }, "/api/v0/main-frontend/course-plans": { "get": { "tags": ["course-plans"], "operationId": "getCourseDesignerPlans", "responses": { "200": { "description": "Plans", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CourseDesignerPlanSummary" } } } } } } }, "post": { "tags": ["course-plans"], "operationId": "createCourseDesignerPlan", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCourseDesignerPlanRequest" } } }, "required": true }, "responses": { "200": { "description": "Created plan", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerPlan" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}": { "get": { "tags": ["course-plans"], "operationId": "getCourseDesignerPlan", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Plan details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerPlanDetails" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/members": { "get": { "tags": ["course-plans"], "operationId": "getCoursePlanMembers", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Plan members", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PlanMemberWithDetails" } } } } } } }, "post": { "tags": ["course-plans"], "operationId": "addCoursePlanMember", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AddPlanMemberRequest" } } }, "required": true }, "responses": { "200": { "description": "Added member", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlanMemberWithDetails" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/members/{user_id}": { "delete": { "tags": ["course-plans"], "operationId": "removeCoursePlanMember", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id to remove", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "204": { "description": "Member removed" } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/schedule": { "put": { "tags": ["course-plans"], "operationId": "saveCourseDesignerSchedule", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SaveCourseDesignerScheduleRequest" } } }, "required": true }, "responses": { "200": { "description": "Updated plan details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerPlanDetails" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/schedule/finalize": { "post": { "tags": ["course-plans"], "operationId": "finalizeCourseDesignerSchedule", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Finalized plan", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerPlan" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/schedule/suggestions": { "post": { "tags": ["course-plans"], "operationId": "createCourseDesignerScheduleSuggestion", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerScheduleSuggestionRequest" } } }, "required": true }, "responses": { "200": { "description": "Suggested schedule", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerScheduleSuggestionResponse" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/stages/advance": { "post": { "tags": ["course-plans"], "operationId": "advanceCourseDesignerStage", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Updated plan details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerPlanDetails" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/stages/{stage_id}/tasks": { "post": { "tags": ["course-plans"], "operationId": "createCourseDesignerStageTask", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "stage_id", "in": "path", "description": "Stage id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CreateCourseDesignerStageTaskRequest" } } }, "required": true }, "responses": { "200": { "description": "Created task", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerPlanStageTask" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/stages/{stage}/extend": { "post": { "tags": ["course-plans"], "operationId": "extendCourseDesignerStage", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "stage", "in": "path", "description": "Stage name", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExtendStageRequest" } } }, "required": true }, "responses": { "200": { "description": "Updated plan details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerPlanDetails" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/stages/{stage}/workspace": { "patch": { "tags": ["course-plans"], "operationId": "updateCourseDesignerStageWorkspace", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "stage", "in": "path", "description": "Stage name", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerStageWorkspace" } } }, "required": true }, "responses": { "200": { "description": "Updated plan details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerPlanDetails" } } } } } } }, "/api/v0/main-frontend/course-plans/{plan_id}/tasks/{task_id}": { "delete": { "tags": ["course-plans"], "operationId": "deleteCourseDesignerStageTask", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "task_id", "in": "path", "description": "Task id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "204": { "description": "Task deleted" } } }, "patch": { "tags": ["course-plans"], "operationId": "updateCourseDesignerStageTask", "parameters": [ { "name": "plan_id", "in": "path", "description": "Plan id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "task_id", "in": "path", "description": "Task id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UpdateCourseDesignerStageTaskRequest" } } }, "required": true }, "responses": { "200": { "description": "Updated task", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseDesignerPlanStageTask" } } } } } } }, "/api/v0/main-frontend/courses": { "post": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/courses` - Create a new course.\n# Example\n\nRequest:\n```http\nPOST /api/v0/main-frontend/courses HTTP/1.1\nContent-Type: application/json\n\n{\n \"name\": \"Introduction to introduction\",\n \"slug\": \"introduction-to-introduction\",\n \"organization_id\": \"1b89e57e-8b57-42f2-9fed-c7a6736e3eec\"\n}\n```", "operationId": "createCourse", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewCourse" } } }, "required": true }, "responses": { "200": { "description": "Created course", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Course" } } } } } } }, "/api/v0/main-frontend/courses/": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses` - Get all courses\n\nReturns all courses.", "operationId": "getAllCourses", "responses": { "200": { "description": "All courses", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Course" } } } } } } } }, "/api/v0/main-frontend/courses/join/{join_code}": { "get": { "tags": ["courses"], "summary": "\nGET /courses/join/:join_code - Gets the course related to join code", "operationId": "getCourseByJoinCode", "parameters": [ { "name": "join_code", "in": "path", "description": "Course join code", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Course for join code", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Course" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:course_id` - Get course.", "operationId": "getCourse", "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" } } } } } }, "put": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/courses/:course_id` - Update course.\n# Example\n\nRequest:\n```http\nPUT /api/v0/main-frontend/courses/ab4541d8-6db4-4561-bdb2-45f35b2544a1 HTTP/1.1\nContent-Type: application/json\n\n{\n \"name\": \"Introduction to Introduction\"\n}\n\n```", "operationId": "updateCourse", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseUpdate" } } }, "required": true }, "responses": { "200": { "description": "Updated course", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Course" } } } } } }, "delete": { "tags": ["courses"], "summary": "\nDELETE `/api/v0/main-frontend/courses/:course_id` - Delete a course.", "operationId": "deleteCourse", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted course", "content": { "application/json": { "schema": {} } } } } } }, "/api/v0/main-frontend/courses/{course_id}/breadcrumb-info": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:course_id/breadcrumb-info` - Get information to display breadcrumbs on the manage course pages.", "operationId": "getCourseBreadcrumbInfo", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course breadcrumb information", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseBreadcrumbInfo" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/chatbots": { "get": { "tags": ["courses"], "summary": "GET `/api/v0/main-frontend/courses/{course_id}/chatbots`", "operationId": "getCourseChatbots", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Course chatbots", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ChatbotConfiguration" } } } } } } }, "post": { "tags": ["courses"], "summary": "POST `/api/v0/main-frontend/courses/{course_id}/chatbots`", "operationId": "createCourseChatbot", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string" } } ], "requestBody": { "description": "JSON string literal chatbot name, e.g. \"Chatbot 1\".", "content": { "application/json": { "schema": { "type": "string" } } }, "required": true }, "responses": { "200": { "description": "Created course chatbot", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatbotConfiguration" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/chatbots/{chatbot_configuration_id}/set-as-default": { "post": { "tags": ["courses"], "summary": "POST `/api/v0/main-frontend/courses/{course_id}/chatbots/{chatbot_configuration_id}/set-as-default`", "operationId": "setCourseChatbotAsDefault", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string" } }, { "name": "chatbot_configuration_id", "in": "path", "description": "Chatbot configuration id", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Updated course chatbot", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatbotConfiguration" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/chatbots/{chatbot_configuration_id}/set-as-non-default": { "post": { "tags": ["courses"], "summary": "POST `/api/v0/main-frontend/courses/{course_id}/chatbots/{chatbot_configuration_id}/set-as-non-default`", "operationId": "setCourseChatbotAsNonDefault", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string" } }, { "name": "chatbot_configuration_id", "in": "path", "description": "Chatbot configuration id", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Updated course chatbot", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChatbotConfiguration" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/course-instances": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/course-instances` - Returns all course instances for given course id.", "operationId": "getCourseInstances", "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/main-frontend/courses/{course_id}/course-module-completions/{user_id}": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:course_id/course-module-completions/:user_id` - Returns all course module completions for a given user for this course.", "operationId": "getCourseModuleCompletionsForUser", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course module completions for course user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CourseModuleCompletion" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/course-modules": { "post": { "tags": ["courses"], "operationId": "updateCourseModules", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ModuleUpdates" } } }, "required": true }, "responses": { "200": { "description": "Course modules updated" } } } }, "/api/v0/main-frontend/courses/{course_id}/course-users-counts-by-exercise": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/course-users-counts-by-exercise` - Returns the amount of users for each exercise.", "operationId": "getCourseUsersCountsByExercise", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course users counts by exercise", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseUserCounts" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/create-copy": { "post": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/courses/:id/create-copy` - Create a copy of a course with specified mode.\n\nDifferent copy modes:\n- `duplicate`: Creates a completely separate copy with new language group\n- `same_language_group`: Creates a new language version within the same language group\n- `existing_language_group`: Creates a new language version in the specified language group\n- `new_language_group`: Creates a new language version in a new language group\n\n# Example\n\nRequest:\n```http\nPOST /api/v0/main-frontend/courses/fd484707-25b6-4c51-a4ff-32d8259e3e47/create-copy HTTP/1.1\nContent-Type: application/json\n\n{\n \"name\": \"Johdatus kaikkeen\",\n \"slug\": \"johdatus-kaikkeen\",\n \"organization_id\": \"1b89e57e-8b57-42f2-9fed-c7a6736e3eec\",\n \"language_code\": \"fi-FI\",\n \"mode\": \"duplicate\"\n}\n```\n\nOr with an existing language group:\n```http\nPOST /api/v0/main-frontend/courses/fd484707-25b6-4c51-a4ff-32d8259e3e47/create-copy HTTP/1.1\nContent-Type: application/json\n\n{\n \"name\": \"Johdatus kaikkeen\",\n \"slug\": \"johdatus-kaikkeen\",\n \"organization_id\": \"1b89e57e-8b57-42f2-9fed-c7a6736e3eec\",\n \"language_code\": \"fi-FI\",\n \"mode\": {\n \"existing_language_group\": {\n \"target_course_id\": \"1b89e57e-8b57-42f2-9fed-c7a6736e3eec\"\n }\n }\n}\n```", "operationId": "createCourseCopy", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CopyCourseRequest" } } }, "required": true }, "responses": { "200": { "description": "Created course copy", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Course" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/daily-submission-counts": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/daily-submission-counts` - Returns submission counts grouped by day.", "operationId": "getCourseDailySubmissionCounts", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course daily submission counts", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseSlideSubmissionCount" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/daily-users-who-have-submitted-something": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/daily-users-who-have-submitted-something` - Returns a count of users who have submitted something grouped by day.", "operationId": "getCourseDailyUsersWhoSubmittedSomething", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course daily user submission counts", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseSlideSubmissionCount" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/default-peer-review": { "get": { "tags": ["courses"], "operationId": "getCourseDefaultPeerReview", "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": {} } } } } } }, "/api/v0/main-frontend/courses/{course_id}/exercises": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/exercises` - Returns all exercises for the course.", "operationId": "getCourseExercises", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercises for course", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Exercise" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/exercises-and-count-of-answers-requiring-attention": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/exercises-and-count-of-answers-requiring-attention` - Returns all exercises for the course and count of answers requiring attention in them.", "operationId": "getCourseExercisesAndAnswersRequiringAttentionCounts", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercises and answer attention counts", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseAnswersInCourseRequiringAttentionCount" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/export-course-instances": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${course.id}/export-course-instances`\n\ngets SCV course instances for course", "operationId": "exportCourseInstancesCsv", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course instances CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/export-course-user-consents": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${course.id}/export-course-user-consents`\n\ngets SCV course specific research form questions and user answers for course", "operationId": "exportCourseUserConsentsCsv", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course user consents CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/export-exercise-tasks": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${course.id}/export-exercise-tasks`\n\ngets SCV all exercise-tasks' private specs in course", "operationId": "exportCourseExerciseTasksCsv", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course exercise tasks CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/export-submissions": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${courseId}/export-submissions`\n\ngets SCV of course exercise submissions", "operationId": "exportCourseSubmissionsCsv", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course submissions CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/export-user-details": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${course.id}/export-user-details`\n\ngets SCV of user details for all users having submitted an exercise in the course", "operationId": "exportCourseUserDetailsCsv", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course user details CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/export-user-exercise-states": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${course.id}/export-user-exercise-states`\n\ngets CSV for course specific user exercise states", "operationId": "exportCourseUserExerciseStatesCsv", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course user exercise states CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/feedback": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/feedback?read=true` - Returns feedback for the given course.", "operationId": "getCourseFeedback", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string" } }, { "name": "read", "in": "query", "description": "Whether to fetch read feedback", "required": true, "schema": { "type": "boolean" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Feedback for the course", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Feedback" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/feedback-count": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/feedback-count` - Returns the amount of feedback for the given course.", "operationId": "getCourseFeedbackCount", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Feedback counts for the course", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/FeedbackCount" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/get-course-audiences": { "get": { "tags": ["courses"], "summary": "\nget `/api/v0/main-frontend/courses/:course_id/get-course-audiences` - Get course audiences.", "operationId": "getCourseAudiences", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course audiences", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CourseAudience" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/get-course-metadata": { "get": { "tags": ["courses"], "summary": "\nget `/api/v0/main-frontend/courses/:course_id/get-course-metadata` - Get course audiences.", "operationId": "getCourseMetadata", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CompleteCourseMetadata" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/get-course-prerequisites": { "get": { "tags": ["courses"], "summary": "\nget `/api/v0/main-frontend/courses/:course_id/get-course-prerequisites` - Get course prerequisites.", "operationId": "getCoursePrerequisites", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course prerequisites", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CoursePrerequisite" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/glossary": { "get": { "tags": ["glossary"], "operationId": "getCourseGlossary", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Glossary terms for the course", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Term" } } } } }, "401": { "description": "Authentication required" }, "403": { "description": "User is not allowed to manage the course glossary" } } }, "post": { "tags": ["glossary"], "operationId": "createCourseGlossaryTerm", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TermUpdate" } } }, "required": true }, "responses": { "200": { "description": "Created glossary term id", "content": { "text/plain": { "schema": { "type": "string", "format": "uuid" } } } }, "401": { "description": "Authentication required" }, "403": { "description": "User is not allowed to manage the course glossary" } } } }, "/api/v0/main-frontend/courses/{course_id}/join-course-with-join-code": { "post": { "tags": ["courses"], "summary": "\nPOST /courses/:course_id/join-course-with-join-code - Adds the user to join_code_uses so the user gets access to the course", "operationId": "joinCourseWithJoinCode", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/JoinCourseWithJoinCodePayload" } } }, "required": true }, "responses": { "200": { "description": "Joined course id", "content": { "text/plain": { "schema": { "type": "string", "format": "uuid" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/language-versions": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/language-versions` - Returns all language versions of the same course.\n\n# Example\n\nRequest:\n```http\nGET /api/v0/main-frontend/courses/fd484707-25b6-4c51-a4ff-32d8259e3e47/language-versions HTTP/1.1\nContent-Type: application/json\n```", "operationId": "getCourseLanguageVersions", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course language versions", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Course" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/new-chapter-ordering": { "post": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/courses/:id/new-chapter-ordering` - Reorders chapters based on modified chapter number.#\n\nCreates redirects if url_path changes.", "operationId": "updateCourseChapterOrdering", "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/Chapter" } } } }, "required": true }, "responses": { "200": { "description": "Course chapter ordering updated" } } } }, "/api/v0/main-frontend/courses/{course_id}/new-course-instance": { "post": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/courses/:id/new-course-instance`", "operationId": "createCourseInstance", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseInstanceForm" } } }, "required": true }, "responses": { "200": { "description": "Created course instance id", "content": { "text/plain": { "schema": { "type": "string", "format": "uuid" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/new-page-ordering": { "post": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/courses/:id/new-page-ordering` - Reorders pages to the given order numbers and given chapters.\n\nNote that the page objects posted here might have the content omitted because it is not needed here and the content makes the request body to be very large.\n\nCreates redirects if url_path changes.", "operationId": "updateCoursePageOrdering", "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/Page" } } } }, "required": true }, "responses": { "200": { "description": "Course page ordering updated" } } } }, "/api/v0/main-frontend/courses/{course_id}/page-visit-datum-summary": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${course.id}/page-visit-datum-summary` - Gets aggregated statistics for page visits for the course.", "operationId": "getCoursePageVisitDatumSummary", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course page visit summary", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PageVisitDatumSummaryByCourse" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/page-visit-datum-summary-by-countries": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${course.id}/page-visit-datum-summary-by-countries` - Gets aggregated statistics for page visits for the course.", "operationId": "getCoursePageVisitDatumSummaryByCountries", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course page visit summary by countries", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PageVisitDatumSummaryByCoursesCountries" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/page-visit-datum-summary-by-device-types": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${course.id}/page-visit-datum-summary-by-device-types` - Gets aggregated statistics for page visits for the course.", "operationId": "getCoursePageVisitDatumSummaryByDeviceTypes", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course page visit summary by device types", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PageVisitDatumSummaryByCourseDeviceTypes" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/page-visit-datum-summary-by-pages": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/${course.id}/page-visit-datum-summary-by-pages` - Gets aggregated statistics for page visits for the course.", "operationId": "getCoursePageVisitDatumSummaryByPages", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course page visit summary by pages", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PageVisitDatumSummaryByPages" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/partners-block": { "get": { "tags": ["courses"], "summary": "\nGET /courses/:course_id/partners_blocks - Gets a partners block related to a course", "operationId": "getCoursePartnersBlock", "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": {} } } } } }, "post": { "tags": ["courses"], "summary": "\n POST /api/v0/main-frontend/courses/:course_id/partners_block - Create or updates a partners block for a course", "operationId": "upsertCoursePartnersBlock", "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", "content": { "application/json": { "schema": {} } } } } }, "delete": { "tags": ["courses"], "summary": "\nDELETE `/api/v0/main-frontend/courses/:course_id` - Delete a partners block in a course.", "operationId": "deleteCoursePartnersBlock", "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": {} } } } } } }, "/api/v0/main-frontend/courses/{course_id}/progress/{user_id}": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:course_id/progress/:user_id` - Returns user progress for the course.", "operationId": "getCourseProgressForUser", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User progress for course", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserCourseProgress" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/references": { "get": { "tags": ["courses"], "operationId": "getCourseReferences", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course references", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/MaterialReference" } } } } } } }, "post": { "tags": ["courses"], "operationId": "createCourseReferences", "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/NewMaterialReference" } } } }, "required": true }, "responses": { "200": { "description": "Course references created" } } } }, "/api/v0/main-frontend/courses/{course_id}/references/{reference_id}": { "post": { "tags": ["courses"], "operationId": "updateCourseReference", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "reference_id", "in": "path", "description": "Reference id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewMaterialReference" } } }, "required": true }, "responses": { "200": { "description": "Course reference updated" } } }, "delete": { "tags": ["courses"], "operationId": "deleteCourseReference", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "reference_id", "in": "path", "description": "Reference id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course reference deleted" } } } }, "/api/v0/main-frontend/courses/{course_id}/reprocess-completions": { "post": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/courses/{course_id}/reprocess-completions`\n\nReprocesses all module completions for the given course instance. Only available to admins.", "operationId": "reprocessCourseCompletions", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course completions reprocessed", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/set-join-code": { "post": { "tags": ["courses"], "summary": "\n POST /api/v0/main-frontend/courses/:course_id/generate-join-code - Generates a code that is used as a part of URL to join course", "operationId": "setCourseJoinCode", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course join code set" } } } }, "/api/v0/main-frontend/courses/{course_id}/sisu-course-llm-descriptions": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:course_id/sisu-course-llm-descriptions` - Get Sisu descriptions summarised by LLM\n\nReturns LLM generated descriptions for a course based on information from Sisu API.", "operationId": "getSisuCourseLlmDescriptions", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Sisu course LLM descriptions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SisuDescriptionResponse" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/all-language-versions/completions-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/all-language-versions/completions-history/{granularity}/{time_window}`", "description": "Returns completion statistics for all language versions with specified time granularity and window.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getCourseCompletionsHistoryAllLanguageVersions", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Course completions history across all language versions", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/all-language-versions/total-users-started": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/all-language-versions/total-users-started`", "operationId": "getTotalUsersStartedAllLanguageVersions", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Total users started across all language versions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CountResult" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/all-language-versions/users-starting-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/all-language-versions/users-starting-history/{granularity}/{time_window}`", "description": "Returns unique users starting statistics for all language versions with specified time granularity and window.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getUniqueUsersStartingHistoryAllLanguageVersions", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Unique users starting history across all language versions", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/avg-time-to-first-submission/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/avg-time-to-first-submission/{granularity}/{time_window}`", "description": "Returns average time to first submission statistics with specified time granularity and window.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getAvgTimeToFirstSubmissionHistory", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Average time to first submission history", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/AverageMetric" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/by-instance/completions-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/by-instance/completions-history/{granularity}/{time_window}`", "description": "Returns course completion statistics with specified time granularity and window, grouped by course instance.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getCourseCompletionsHistoryByInstance", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Course completions history by instance", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } }, "propertyNames": { "type": "string", "format": "uuid" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/by-instance/first-submissions-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/by-instance/first-submissions-history/{granularity}/{time_window}`", "description": "Returns first exercise submission statistics with specified time granularity and window, grouped by course instance.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getFirstExerciseSubmissionsHistoryByInstance", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "First exercise submissions history by instance", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } }, "propertyNames": { "type": "string", "format": "uuid" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/by-instance/total-users-completed": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/by-instance/total-users-completed`", "operationId": "getTotalUsersCompletedCourseByInstance", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Total users completed course by instance", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/CountResult" }, "propertyNames": { "type": "string", "format": "uuid" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/by-instance/total-users-returned-exercises": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/by-instance/total-users-returned-exercises`", "operationId": "getTotalUsersReturnedExercisesByInstance", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Total users returned exercises by instance", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/CountResult" }, "propertyNames": { "type": "string", "format": "uuid" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/by-instance/total-users-started-course": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/by-instance/total-users-started-course`", "operationId": "getTotalUsersStartedCourseByInstance", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Total users started course by instance", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/CountResult" }, "propertyNames": { "type": "string", "format": "uuid" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/by-instance/users-returning-exercises-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/by-instance/users-returning-exercises-history/{granularity}/{time_window}`", "description": "Returns users returning exercises statistics with specified time granularity and window, grouped by course instance.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getUsersReturningExercisesHistoryByInstance", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Users returning exercises history by instance", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } }, "propertyNames": { "type": "string", "format": "uuid" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/by-instance/users-starting-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/by-instance/users-starting-history/{granularity}/{time_window}`", "description": "Returns unique users starting statistics with specified time granularity and window, grouped by course instance.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getUniqueUsersStartingHistoryByInstance", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Unique users starting history by instance", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } }, "propertyNames": { "type": "string", "format": "uuid" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/by-module/first-submissions/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/by-module/first-submissions/{granularity}/{time_window}`", "description": "Returns first exercise submission statistics with specified time granularity and window,\ngrouped by module.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getFirstExerciseSubmissionsByModule", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "First exercise submissions by module", "content": { "application/json": { "schema": { "type": "object", "additionalProperties": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } }, "propertyNames": { "type": "string", "format": "uuid" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/cohort-activity/{granularity}/{history_window}/{tracking_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/cohort-activity/{granularity}/{history_window}/{tracking_window}`", "operationId": "getCohortActivityHistory", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "history_window", "in": "path", "description": "History window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "tracking_window", "in": "path", "description": "Tracking window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Cohort activity history", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CohortActivity" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/completions-history/custom-time-period/{start_date}/{end_date}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/completions-history/custom-time-period/{start_date}/{end_date}`", "description": "Returns completion statistics by custom time period.\nQuery parameters:\n- start_date: YYYY-MM-DD\n- end_date: YYYY-MM-DD", "operationId": "getCourseCompletionsHistoryCustomTimePeriod", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "path", "description": "Start date", "required": true, "schema": { "type": "string" } }, { "name": "end_date", "in": "path", "description": "End date", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Course completions history for custom time period", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/completions-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/completions-history/{granularity}/{time_window}`", "description": "Returns completion statistics for the course with specified time granularity and window.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getCourseCompletionsHistory", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Course completions history", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/first-submissions-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/first-submissions-history/{granularity}/{time_window}`", "description": "Returns first exercise submission statistics with specified time granularity and window.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getFirstExerciseSubmissionsHistory", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "First exercise submissions history", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/student-completions-by-country/{granularity}/{time_window}/{country}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/student-completions-by-country/{granularity}/{time_window}/{country}`", "description": "Returns student completion statistics grouped by country with the specified time granularity.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getStudentCompletionsByCountry", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "country", "in": "path", "description": "Country", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Student completions by country", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/student-enrollments-by-country/{granularity}/{time_window}/{country}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/student-enrollments-by-country/{granularity}/{time_window}/{country}`", "description": "Returns student signup statistics grouped by country with the specified time granularity.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getStudentEnrollmentsByCountry", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "country", "in": "path", "description": "Country", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Student enrollments by country", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/students-by-country-totals": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/students-by-country-totals`", "description": "Returns all enrolled students grouped by country.", "operationId": "getStudentsByCountryTotals", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Students by country totals", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/StudentsByCountryTotalsResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/total-users-completed": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/total-users-completed`", "operationId": "getTotalUsersCompletedCourse", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Total users completed course", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CountResult" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/total-users-completed/custom-time-period/{start_date}/{end_date}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/total-users-completed/custom-time-period/{start_date}/{end_date}`", "operationId": "getTotalUsersCompletedCourseCustomTimePeriod", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "path", "description": "Start date", "required": true, "schema": { "type": "string" } }, { "name": "end_date", "in": "path", "description": "End date", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Total users completed course for custom time period", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CountResult" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/total-users-returned-exercises": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/total-users-returned-exercises`", "operationId": "getTotalUsersReturnedExercises", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Total users returned exercises", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CountResult" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/total-users-returned-exercises/custom-time-period/{start_date}/{end_date}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/total-users-returned-exercises/custom-time-period/{start_date}/{end_date}`", "operationId": "getTotalUsersReturnedExercisesCustomTimePeriod", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "path", "description": "Start date", "required": true, "schema": { "type": "string" } }, { "name": "end_date", "in": "path", "description": "End date", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Total users returned exercises for custom time period", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CountResult" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/total-users-started-course": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/total-users-started-course`", "operationId": "getTotalUsersStartedCourse", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Total users started course", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CountResult" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/total-users-started-course/custom-time-period/{start_date}/{end_date}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/total-users-started-course/custom-time-period/{start_date}/{end_date}`", "operationId": "getTotalUsersStartedCourseCustomTimePeriod", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "path", "description": "Start date", "required": true, "schema": { "type": "string" } }, { "name": "end_date", "in": "path", "description": "End date", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Total users started course for custom time period", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CountResult" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/users-returning-exercises-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/users-returning-exercises-history/{granularity}/{time_window}`", "description": "Returns users returning exercises statistics with specified time granularity and window.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getUsersReturningExercisesHistory", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Users returning exercises history", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/users-starting-history/custom-time-period/{start_date}/{end_date}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/users-starting-history/custom-time-period/{start_date}/{end_date}`", "description": "Returns unique users starting statistics with specified time period.", "operationId": "getUniqueUsersStartingHistoryCustomTimePeriod", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "start_date", "in": "path", "description": "Start date", "required": true, "schema": { "type": "string" } }, { "name": "end_date", "in": "path", "description": "End date", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Unique users starting history for custom time period", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/stats/users-starting-history/{granularity}/{time_window}": { "get": { "tags": ["course-stats"], "summary": "GET `/api/v0/main-frontend/{course_id}/stats/users-starting-history/{granularity}/{time_window}`", "description": "Returns unique users starting statistics with specified time granularity and window.\n- granularity: \"year\", \"month\", or \"day\"\n- time_window: number of time units to look back", "operationId": "getUniqueUsersStartingHistory", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "granularity", "in": "path", "description": "Time granularity", "required": true, "schema": { "$ref": "#/components/schemas/TimeGranularity" } }, { "name": "time_window", "in": "path", "description": "Time window", "required": true, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Unique users starting history", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CountResult" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/status-for-all-exercises/{user_id}": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:course_id/status-for-all-exercises/:user_id` - Returns status for all exercises in the course for a given user.", "operationId": "getCourseExerciseStatusesForUser", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercise statuses for course user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseStatusSummaryForUser" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/structure": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:course_id/structure` - Returns the structure of a course.\n# Example\n```json\n{\n \"course\": {\n \"id\": \"d86cf910-4d26-40e9-8c9c-1cc35294fdbb\",\n \"slug\": \"introduction-to-everything\",\n \"created_at\": \"2021-04-28T10:40:54.503917\",\n \"updated_at\": \"2021-04-28T10:40:54.503917\",\n \"name\": \"Introduction to everything\",\n \"organization_id\": \"1b89e57e-8b57-42f2-9fed-c7a6736e3eec\",\n \"deleted_at\": null,\n \"language_code\": \"en-US\",\n \"copied_from\": null,\n \"language_version_of_course_id\": null\n },\n \"pages\": [\n {\n \"id\": \"f3b0d699-c9be-4d56-bd0a-9d40e5547e4d\",\n \"created_at\": \"2021-04-28T13:51:51.024118\",\n \"updated_at\": \"2021-04-28T14:36:18.179490\",\n \"course_id\": \"d86cf910-4d26-40e9-8c9c-1cc35294fdbb\",\n \"content\": [],\n \"url_path\": \"/\",\n \"title\": \"Welcome to Introduction to Everything\",\n \"deleted_at\": null,\n \"chapter_id\": \"d332f3d9-39a5-4a18-80f4-251727693c37\"\n }\n ],\n \"chapters\": [\n {\n \"id\": \"d332f3d9-39a5-4a18-80f4-251727693c37\",\n \"created_at\": \"2021-04-28T16:11:47.477850\",\n \"updated_at\": \"2021-04-28T16:11:47.477850\",\n \"name\": \"The Basics\",\n \"course_id\": \"d86cf910-4d26-40e9-8c9c-1cc35294fdbb\",\n \"deleted_at\": null,\n \"chapter_image_url\": \"http://project-331.local/api/v0/files/uploads/organizations/1b89e57e-8b57-42f2-9fed-c7a6736e3eec/courses/d86cf910-4d26-40e9-8c9c-1cc35294fdbb/images/mbPQh8th96TdUwX96Y0ch1fjbJLRFr.png\",\n \"chapter_number\": 1,\n \"front_page_id\": null\n }\n ]\n}\n```", "operationId": "getCourseStructure", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course structure", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseStructure" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/students/certificates": { "post": { "tags": ["course-students"], "summary": "POST `/api/v0/main-frontend/courses/{course_id}/students/certificates`", "operationId": "getCourseStudentsCertificates", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserIdsPayload" } } }, "required": true }, "responses": { "200": { "description": "Course certificates for the given users", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CertificateGridRow" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/students/completions": { "post": { "tags": ["course-students"], "summary": "POST `/api/v0/main-frontend/courses/{course_id}/students/completions`", "operationId": "getCourseStudentsCompletions", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserIdsPayload" } } }, "required": true }, "responses": { "200": { "description": "Course completions for the given users", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CompletionGridRow" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/students/progress": { "post": { "tags": ["course-students"], "summary": "POST `/api/v0/main-frontend/courses/{course_id}/students/progress`", "operationId": "getCourseStudentsProgress", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserIdsPayload" } } }, "required": true }, "responses": { "200": { "description": "Per-user course progress for the given users", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseStudentsProgressUsers" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/students/progress-structure": { "get": { "tags": ["course-students"], "summary": "GET `/api/v0/main-frontend/courses/{course_id}/students/progress-structure`", "operationId": "getCourseStudentsProgressStructure", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course-level progress structure", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseStudentsProgressStructure" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/students/users": { "get": { "tags": ["course-students"], "summary": "GET `/api/v0/main-frontend/courses/{course_id}/students/users`", "operationId": "getCourseStudentsUsers", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "page", "in": "query", "description": "Page number (1-based)", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "limit", "in": "query", "description": "Page size (1-10000)", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "search", "in": "query", "description": "Filter by name/email substring or exact user id", "required": false, "schema": { "type": "string" } }, { "name": "sort_column", "in": "query", "description": "last_name | first_name | email", "required": false, "schema": { "type": "string" } }, { "name": "sort_direction", "in": "query", "description": "asc | desc", "required": false, "schema": { "type": "string" } }, { "name": "course_instance_id", "in": "query", "description": "Filter to a single course instance", "required": false, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "A page of enrolled students", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/StudentsListPage" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/students/{user_id}/chapter-locking-statuses": { "get": { "tags": ["course-students"], "summary": "GET `/api/v0/main-frontend/courses/{course_id}/students/{user_id}/chapter-locking-statuses`", "operationId": "getCourseStudentChapterLockingStatuses", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "Target student id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Student chapter locking statuses", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserChapterLockingStatus" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/students/{user_id}/chapters/{chapter_id}/lock": { "post": { "tags": ["course-students"], "summary": "POST `/api/v0/main-frontend/courses/{course_id}/students/{user_id}/chapters/{chapter_id}/lock`", "operationId": "teacherLockStudentChapter", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "Target student id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "chapter_id", "in": "path", "description": "Chapter id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Updated chapter locking status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserChapterLockingStatus" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/students/{user_id}/chapters/{chapter_id}/status": { "post": { "tags": ["course-students"], "summary": "POST `/api/v0/main-frontend/courses/{course_id}/students/{user_id}/chapters/{chapter_id}/status`", "operationId": "teacherSetStudentChapterStatus", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "Target student id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "chapter_id", "in": "path", "description": "Chapter id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChapterLockStatusActionPayload" } } }, "required": true }, "responses": { "200": { "description": "Updated chapter locking status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserChapterLockingStatus" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/students/{user_id}/chapters/{chapter_id}/unlock": { "post": { "tags": ["course-students"], "summary": "POST `/api/v0/main-frontend/courses/{course_id}/students/{user_id}/chapters/{chapter_id}/unlock`", "operationId": "teacherUnlockStudentChapter", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "Target student id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "chapter_id", "in": "path", "description": "Chapter id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Updated chapter locking status", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserChapterLockingStatus" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/submission-counts-by-exercise": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/submission-counts-by-exercise` - Returns submission counts grouped by weekday and hour.", "operationId": "getCourseSubmissionCountsByExercise", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course submission counts by exercise", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseSlideSubmissionCountByExercise" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/suspected-cheaters": { "get": { "tags": ["courses"], "summary": "\n GET /api/v0/main-frontend/courses/${course.id}/suspected-cheaters?status=Flagged - returns the suspected cheaters in the given review state for a course.", "operationId": "getCourseSuspectedCheaters", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "status", "in": "query", "description": "Which review state of suspected cheaters to fetch", "required": true, "schema": { "$ref": "#/components/schemas/SuspectedCheaterStatus" } } ], "responses": { "200": { "description": "Suspected cheaters for course", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/SuspectedCheaters" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/suspected-cheaters/confirm/{user_id}": { "post": { "tags": ["courses"], "summary": "\n POST /api/v0/main-frontend/courses/${course.id}/suspected-cheaters/confirm/:user_id - confirms the student cheated (sets status to 'ConfirmedCheating') and fails the student.", "operationId": "confirmCourseSuspectedCheater", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "Suspected cheater's user id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Cheating confirmed" } } } }, "/api/v0/main-frontend/courses/{course_id}/suspected-cheaters/dismiss/{user_id}": { "post": { "tags": ["courses"], "summary": "\n POST /api/v0/main-frontend/courses/${course.id}/suspected-cheaters/dismiss/:user_id - dismisses the suspicion as a false alarm (sets status to 'Dismissed').", "operationId": "dismissCourseSuspectedCheater", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "Suspected cheater's user id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Suspicion dismissed" } } } }, "/api/v0/main-frontend/courses/{course_id}/suspected-cheaters/flagged-count": { "get": { "tags": ["courses"], "summary": "\n GET /api/v0/main-frontend/courses/${course.id}/suspected-cheaters/flagged-count - number of suspected cheaters awaiting review (status flagged). Used to show a review notification to teachers.", "operationId": "getCourseFlaggedSuspectedCheatersCount", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Number of suspected cheaters awaiting review", "content": { "application/json": { "schema": { "type": "integer", "format": "int64" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/teacher-reset-course-progress-for-everyone": { "delete": { "tags": ["courses"], "summary": "\nDELETE `/api/v0/main-frontend/courses/${course.id}/teacher-reset-course-progress-for-everyone` - Can be used by teachers to reset the course progress for all students. Only works when the course is a draft and not published to students. Cannot be used to delete a course that some students have taken.\n\nDeletes submissions, user exercise states, and peer reviews etc. for all the course instances of this course.", "operationId": "resetCourseProgressForEveryone", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course progress reset for everyone", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/teacher-reset-course-progress-for-themselves": { "delete": { "tags": ["courses"], "summary": "\nDELETE `/api/v0/main-frontend/courses/${course.id}/teacher-reset-course-progress-for-themselves` - Allows a teacher to reset the course progress for themselves. Cannot be used to reset the course for others.\n\nDeletes submissions, user exercise states, and peer reviews etc. for all the course instances of this course.", "operationId": "resetCourseProgressForTeacherThemselves", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Teacher course progress reset", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/thresholds": { "get": { "tags": ["courses"], "summary": "\n GET /api/v0/main-frontend/courses/${course.id}/thresholds - get all thresholds for all modules in a course.", "operationId": "getCourseThresholds", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course thresholds", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CourseModuleThresholdInfo" } } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/update-metadata": { "post": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/courses/:course_id/update-metadata` - Update metadata.", "operationId": "updateMetadata", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseMetadataUpdate" } } }, "required": true }, "responses": { "200": { "description": "Updated metadata", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseMetadata" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/update-peer-review-queue-reviews-received": { "post": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/courses/${course_id}/update-peer-review-queue-reviews-received`\n\nUpdates reviews received for all the students in the peer review queue for a specific course. Updates only entries that have not received enough peer reviews in the table. Only available to admins.", "operationId": "updateCoursePeerReviewQueueReviewsReceived", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Peer review queue updated", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/upload": { "post": { "tags": ["courses"], "summary": "\nPOST `/api/v0/main-frontend/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/main-frontend/pages/d86cf910-4d26-40e9-8c9c-1cc35294fdbb/upload HTTP/1.1\nContent-Type: multipart/form-data\n\nBINARY_DATA\n```", "operationId": "uploadCourseMedia", "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/main-frontend/courses/{course_id}/user-settings/{user_id}": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:course_id/user-settings/:user_id` - Get current course settings for a specific user.", "operationId": "getCourseUserSettingsForUser", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User course settings", "content": { "application/json": { "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/UserCourseSettings" } ] } } } } } } }, "/api/v0/main-frontend/courses/{course_id}/weekday-hour-submission-counts": { "get": { "tags": ["courses"], "summary": "\nGET `/api/v0/main-frontend/courses/:id/weekday-hour-submission-counts` - Returns submission counts grouped by weekday and hour.", "operationId": "getCourseWeekdayHourSubmissionCounts", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course weekday and hour submission counts", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseSlideSubmissionCountByWeekAndHour" } } } } } } } }, "/api/v0/main-frontend/email-templates": { "get": { "tags": ["email_templates"], "summary": "\nGET `/api/v0/main-frontend/email-templates`", "operationId": "getEmailTemplates", "responses": { "200": { "description": "Email templates", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/EmailTemplate" } } } } } } } }, "/api/v0/main-frontend/email-templates/{email_template_id}": { "delete": { "tags": ["email_templates"], "summary": "\nDELETE `/api/v0/main-frontend/email-templates/:id`", "operationId": "deleteEmailTemplate", "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/main-frontend/exams/{exam_id}/exam-exercises": { "get": { "tags": ["exams"], "summary": "\nGET `/api/v0/main-frontend/exam/:exam_id/exam-exercises` - Returns all the exercises with exam_id.", "operationId": "getExamExercises", "parameters": [ { "name": "exam_id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exam exercises", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Exercise" } } } } } } } }, "/api/v0/main-frontend/exams/{exam_id}/release-grades": { "post": { "tags": ["exams"], "summary": "\nPOST `/api/v0/main-frontend/exam/:exam_id/release-grades` - Publishes grading results of an exam by updating user_exercise_states according to teacher_grading_decisons and changes teacher_grading_decisions hidden field to false. Takes teacher grading decision ids as input.", "operationId": "releaseExamGrades", "parameters": [ { "name": "exam_id", "in": "path", "description": "Exam 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": "Exam grades released" } } } }, "/api/v0/main-frontend/exams/{exam_id}/submissions-with-exam-id": { "get": { "tags": ["exams"], "summary": "\nGET `/api/v0/main-frontend/exam/:exam_id/submissions-with-exam-id` - Returns all the exercise submissions and user exercise states with exam_id.", "operationId": "getExamSubmissionsWithExamId", "parameters": [ { "name": "exam_id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Exercise submissions with exam id", "content": { "application/json": { "schema": { "type": "array", "items": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseSlideSubmissionAndUserExerciseState" } } } } } } } } }, "/api/v0/main-frontend/exams/{exercise_id}/submissions-with-exercise-id": { "get": { "tags": ["exams"], "summary": "\nGET `/api/v0/main-frontend/exam/:exercise_id/submissions-with-exercise_id` - Returns all the exercise submissions and user exercise states with exercise_id.", "operationId": "getExamSubmissionsWithExerciseId", "parameters": [ { "name": "exercise_id", "in": "path", "description": "Exercise id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int32", "minimum": 0 } } ], "responses": { "200": { "description": "Exercise submissions with exercise id", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseSlideSubmissionAndUserExerciseStateList" } } } } } } }, "/api/v0/main-frontend/exams/{id}": { "get": { "tags": ["exams"], "summary": "\nGET `/api/v0/main-frontend/exams/:id", "operationId": "getExam", "parameters": [ { "name": "id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exam", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Exam" } } } } } } }, "/api/v0/main-frontend/exams/{id}/duplicate": { "post": { "tags": ["exams"], "summary": "\n * POST `/api/v0/cms/exams/:exam_id/duplicate` - duplicates existing exam.", "operationId": "duplicateExam", "parameters": [ { "name": "id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewExam" } } }, "required": true }, "responses": { "200": { "description": "Exam duplicated", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/exams/{id}/edit-exam": { "post": { "tags": ["exams"], "summary": "\nPOST `/api/v0/main-frontend/organizations/{organization_id}/edit-exam` - edits an exam.", "operationId": "editExam", "parameters": [ { "name": "id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewExam" } } }, "required": true }, "responses": { "200": { "description": "Exam edited" } } } }, "/api/v0/main-frontend/exams/{id}/export-points": { "get": { "tags": ["exams"], "summary": "\nGET `/api/v0/main-frontend/exams/:id/export-points`", "operationId": "exportExamPointsCsv", "parameters": [ { "name": "id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exam points CSV export", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/exams/{id}/export-submissions": { "get": { "tags": ["exams"], "summary": "\nGET `/api/v0/main-frontend/exams/:id/export-submissions`", "operationId": "exportExamSubmissionsCsv", "parameters": [ { "name": "id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exam submissions CSV export", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/exams/{id}/set": { "post": { "tags": ["exams"], "summary": "\nPOST `/api/v0/main-frontend/exams/:id/set`", "operationId": "setExamCourse", "parameters": [ { "name": "id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExamCourseInfo" } } }, "required": true }, "responses": { "200": { "description": "Course set for exam" } } } }, "/api/v0/main-frontend/exams/{id}/unset": { "post": { "tags": ["exams"], "summary": "\nPOST `/api/v0/main-frontend/exams/:id/unset`", "operationId": "unsetExamCourse", "parameters": [ { "name": "id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExamCourseInfo" } } }, "required": true }, "responses": { "200": { "description": "Course unset from exam" } } } }, "/api/v0/main-frontend/exercise-repositories/course/{course_id}": { "get": { "tags": ["exercise_repositories"], "summary": "\nGET `/api/v0/main-frontend/exercise-repositories/course/:id`", "operationId": "getExerciseRepositoriesForCourse", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercise repositories for course", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseRepository" } } } } } } } }, "/api/v0/main-frontend/exercise-repositories/exam/{exam_id}": { "get": { "tags": ["exercise_repositories"], "summary": "\nGET `/api/v0/main-frontend/exercise-repositories/exam/:id`", "operationId": "getExerciseRepositoriesForExam", "parameters": [ { "name": "exam_id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercise repositories for exam", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseRepository" } } } } } } } }, "/api/v0/main-frontend/exercise-repositories/new": { "post": { "tags": ["exercise_repositories"], "summary": "\nPOST `/api/v0/main-frontend/exercise-repositories/new", "operationId": "createExerciseRepository", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewExerciseRepository" } } }, "required": true }, "responses": { "200": { "description": "Created exercise repository id", "content": { "text/plain": { "schema": { "type": "string", "format": "uuid" } } } } } } }, "/api/v0/main-frontend/exercise-repositories/{id}": { "put": { "tags": ["exercise_repositories"], "summary": "\nPUT `/api/v0/main-frontend/exercise-repositories/:id`", "operationId": "updateExerciseRepository", "parameters": [ { "name": "id", "in": "path", "description": "Exercise repository id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseRepositoryUpdate" } } }, "required": true }, "responses": { "200": { "description": "Updated exercise repository", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } }, "delete": { "tags": ["exercise_repositories"], "summary": "\nDELETE `/api/v0/main-frontend/exercise-repositories/:id`", "operationId": "deleteExerciseRepository", "parameters": [ { "name": "id", "in": "path", "description": "Exercise repository id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted exercise repository", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/exercise-services/": { "get": { "tags": ["exercise_services"], "summary": "\nGET `/api/v0/main-frontend/exercise-services`", "operationId": "getExerciseServices", "responses": { "200": { "description": "Exercise services", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseService" } } } } } } }, "post": { "tags": ["exercise_services"], "summary": "\nPOST `/api/v0/main-frontend/exercise-services`", "operationId": "createExerciseService", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseServiceNewOrUpdate" } } }, "required": true }, "responses": { "200": { "description": "Created exercise service", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseServiceWithError" } } } } } } }, "/api/v0/main-frontend/exercise-services/{exercise_service_id}": { "get": { "tags": ["exercise_services"], "summary": "\nGET `/api/v0/main-frontend/exercise-services/:id`", "operationId": "getExerciseServiceById", "parameters": [ { "name": "exercise_service_id", "in": "path", "description": "Exercise service id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercise service", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseService" } } } } } }, "put": { "tags": ["exercise_services"], "summary": "\nPUT `/api/v0/main-frontend/exercise-services/:id`", "operationId": "updateExerciseService", "parameters": [ { "name": "exercise_service_id", "in": "path", "description": "Exercise service id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseServiceNewOrUpdate" } } }, "required": true }, "responses": { "200": { "description": "Updated exercise service", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseServiceWithError" } } } } } }, "delete": { "tags": ["exercise_services"], "operationId": "deleteExerciseService", "parameters": [ { "name": "exercise_service_id", "in": "path", "description": "Exercise service id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted exercise service", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseService" } } } } } } }, "/api/v0/main-frontend/exercise-slide-submissions/add-teacher-grading-for-exam-submission": { "put": { "tags": ["exercise_slide_submissions"], "summary": "\nPUT `/api/v0/main-frontend/exercise-slide-submissions/add_teacher_grading\"` - Adds a new teacher grading decision, without updating user exercise state", "operationId": "addTeacherGradingForExamSubmission", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewTeacherGradingDecision" } } }, "required": true }, "responses": { "200": { "description": "Created teacher grading decision", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TeacherGradingDecision" } } } } } } }, "/api/v0/main-frontend/exercise-slide-submissions/{exam_id}/user-exercise-state-info": { "get": { "tags": ["exercise_slide_submissions"], "summary": "\nGET `/api/v0/main-frontend/exercise-slide-submissions/{exam_id}/{exercise_id}/{user_id}/user-exercise-state-info`-", "operationId": "getExamUserExerciseStateInfo", "parameters": [ { "name": "exam_id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "exercise_id", "in": "query", "description": "Exercise id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "query", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User exercise state for the exam submission", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserExerciseState" } } } } } } }, "/api/v0/main-frontend/exercise-slide-submissions/{submission_id}/info": { "get": { "tags": ["exercise_slide_submissions"], "summary": "\nGET `/api/v0/main-frontend/exercise-slide-submissions/{submission_id}/info\"`- Returns data necessary for rendering a submission.", "operationId": "getExerciseSlideSubmissionInfo", "parameters": [ { "name": "submission_id", "in": "path", "description": "Exercise slide submission id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercise slide submission info", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseSlideSubmissionInfo" } } } } } } }, "/api/v0/main-frontend/exercises/{course_id}/exercises-by-course-id": { "get": { "tags": ["exercises"], "summary": "\nGET `/api/v0/main-frontend/exercises/:course_id/exercises-by-course-id` - Returns all exercises for a course with course_id", "operationId": "getExercisesByCourseId", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercises by course id", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Exercise" } } } } } } } }, "/api/v0/main-frontend/exercises/{course_id}/reset-exercises-for-selected-users": { "post": { "tags": ["exercises"], "summary": "\nPOST `/api/v0/main-frontend/exercises/:course_id/reset-exercises-for-selected-users` - Resets all selected exercises for selected users and then logs the resets to exercise_reset_logs table", "operationId": "resetExercisesForSelectedUsers", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResetExercisesPayload" } } }, "required": true }, "responses": { "200": { "description": "Number of successful resets", "content": { "text/plain": { "schema": { "type": "integer", "format": "int32" } } } } } } }, "/api/v0/main-frontend/exercises/{exercise_id}": { "get": { "tags": ["exercises"], "summary": "\nGET `/api/v0/main-frontend/exercises/:exercise_id` - Returns a single exercise.", "operationId": "getExercise", "parameters": [ { "name": "exercise_id", "in": "path", "description": "Exercise id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercise", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Exercise" } } } } } } }, "/api/v0/main-frontend/exercises/{exercise_id}/answers-requiring-attention": { "get": { "tags": ["exercises"], "summary": "\nGET `/api/v0/main-frontend/exercises/:exercise_id/answers-requiring-attention` - Returns an exercise's answers requiring attention.", "operationId": "getExerciseAnswersRequiringAttention", "parameters": [ { "name": "exercise_id", "in": "path", "description": "Exercise id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Answers requiring attention", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/AnswersRequiringAttention" } } } } } } }, "/api/v0/main-frontend/exercises/{exercise_id}/csv-export-task-options": { "get": { "tags": ["exercises"], "summary": "\nGET `/api/v0/main-frontend/exercises/:exercise_id/csv-export-task-options` - Returns available exercise tasks and CSV export support flags for each task's exercise service.", "operationId": "getExerciseCsvExportTaskOptions", "parameters": [ { "name": "exercise_id", "in": "path", "description": "Exercise id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercise CSV export task options", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseCsvExportTaskOption" } } } } } } } }, "/api/v0/main-frontend/exercises/{exercise_id}/export-answers-csv": { "get": { "tags": ["exercises"], "summary": "\nGET `/api/v0/main-frontend/exercises/:exercise_id/export-answers-csv` - Exports all answers for one exercise task as CSV using the task's exercise service.", "operationId": "exportExerciseAnswersCsv", "parameters": [ { "name": "exercise_id", "in": "path", "description": "Exercise id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "exercise_task_id", "in": "query", "description": "Exercise task id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "only_latest_per_user", "in": "query", "description": "Only include latest submission per user", "required": false, "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "Exercise answers CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/exercises/{exercise_id}/export-definitions-csv": { "get": { "tags": ["exercises"], "summary": "\nGET `/api/v0/main-frontend/exercises/:exercise_id/export-definitions-csv` - Exports one exercise task definition as CSV using the task's exercise service.", "operationId": "exportExerciseDefinitionsCsv", "parameters": [ { "name": "exercise_id", "in": "path", "description": "Exercise id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "exercise_task_id", "in": "query", "description": "Exercise task id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "only_latest_per_user", "in": "query", "description": "Only include latest submission per user", "required": false, "schema": { "type": "boolean" } } ], "responses": { "200": { "description": "Exercise definitions CSV", "content": { "text/csv": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/exercises/{exercise_id}/submissions": { "get": { "tags": ["exercises"], "summary": "\nGET `/api/v0/main-frontend/exercises/:exercise_id/submissions` - Returns an exercise's submissions.", "operationId": "getExerciseSubmissions", "parameters": [ { "name": "exercise_id", "in": "path", "description": "Exercise id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Exercise submissions", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseSubmissions" } } } } } } }, "/api/v0/main-frontend/exercises/{exercise_id}/submissions/user/{user_id}": { "get": { "tags": ["exercises"], "summary": "\nGET `/api/v0/main-frontend/exercises/:exercise_id/submissions/user/:user_id` - Returns an exercise's submissions for a user.", "operationId": "getExerciseSubmissionsForUser", "parameters": [ { "name": "exercise_id", "in": "path", "description": "Exercise id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Exercise submissions for user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseSlideSubmission" } } } } } } } }, "/api/v0/main-frontend/feedback/{feedback_id}": { "post": { "tags": ["feedback"], "summary": "\nPOST `/api/v0/main-frontend/feedback/:id` - Creates new feedback.", "operationId": "markFeedbackAsRead", "parameters": [ { "name": "feedback_id", "in": "path", "description": "Feedback id", "required": true, "schema": { "type": "string" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/MarkAsRead" } } }, "required": true }, "responses": { "200": { "description": "Feedback read state updated" } } } }, "/api/v0/main-frontend/global-stats/completion-stats-by-email-domain": { "get": { "tags": ["global-stats"], "summary": "\n * GET `/api/v0/main-frontend/global-stats/completion-stats-by-email-domain`\n *\n * Query parameters:\n * - year: Optional - Filter results to specific year (e.g. ?year=2023)", "operationId": "getCompletionStatsByEmailDomain", "parameters": [ { "name": "year", "in": "query", "description": "Optional year", "required": false, "schema": { "type": "integer", "format": "int32" } } ], "responses": { "200": { "description": "Completion stats by email domain", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DomainCompletionStats" } } } } } } } }, "/api/v0/main-frontend/global-stats/course-completion-stats-for-email-domain": { "get": { "tags": ["global-stats"], "summary": "\n * GET `/api/v0/main-frontend/global-stats/course-completion-stats-for-email-domain`\n *\n * Query parameters:\n * - email_domain: String - The email domain to get stats for (required)\n * - year: Optional - Filter results to specific year (e.g. ?year=2023)", "operationId": "getCourseCompletionStatsForEmailDomain", "parameters": [ { "name": "email_domain", "in": "query", "description": "Email domain", "required": true, "schema": { "type": "string" } }, { "name": "year", "in": "query", "description": "Optional year", "required": false, "schema": { "type": "integer", "format": "int32" } } ], "responses": { "200": { "description": "Course completion stats for email domain", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CourseCompletionStats" } } } } } } } }, "/api/v0/main-frontend/global-stats/course-module-stats-by-completions-registered-to-study-registry": { "get": { "tags": ["global-stats"], "summary": "\n * GET `/api/v0/main-frontend/global-stats/course-module-stats-by-completions-registered-to-study-registry`\n *\n * Query parameters:\n * - granularity: String - Either \"year\" or \"month\" (defaults to \"year\")", "operationId": "getCourseModuleStatsByCompletionsRegisteredToStudyRegistry", "parameters": [ { "name": "granularity", "in": "query", "description": "Time granularity", "required": false, "schema": { "$ref": "#/components/schemas/TimeGranularity" } } ], "responses": { "200": { "description": "Course module completion stats", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/GlobalCourseModuleStatEntry" } } } } } } } }, "/api/v0/main-frontend/global-stats/number-of-people-completed-a-course": { "get": { "tags": ["global-stats"], "summary": "\nGET `/api/v0/main-frontend/global-stats/number-of-people-completed-a-course`\n\nQuery parameters:\n- granularity: String - Either \"year\" or \"month\" (defaults to \"year\")", "operationId": "getNumberOfPeopleCompletedACourse", "parameters": [ { "name": "granularity", "in": "query", "description": "Time granularity", "required": false, "schema": { "$ref": "#/components/schemas/TimeGranularity" } } ], "responses": { "200": { "description": "Global completion stats", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/GlobalStatEntry" } } } } } } } }, "/api/v0/main-frontend/global-stats/number-of-people-done-at-least-one-exercise": { "get": { "tags": ["global-stats"], "summary": "\nGET `/api/v0/main-frontend/global-stats/number-of-people-done-at-least-one-exercise`\n\nQuery parameters:\n- granularity: String - Either \"year\" or \"month\" (defaults to \"year\")", "operationId": "getNumberOfPeopleDoneAtLeastOneExercise", "parameters": [ { "name": "granularity", "in": "query", "description": "Time granularity", "required": false, "schema": { "$ref": "#/components/schemas/TimeGranularity" } } ], "responses": { "200": { "description": "Exercise participation stats", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/GlobalStatEntry" } } } } } } } }, "/api/v0/main-frontend/global-stats/number-of-people-registered-completion-to-study-registry": { "get": { "tags": ["global-stats"], "summary": "\nGET `/api/v0/main-frontend/global-stats/number-of-people-registered-completion-to-study-registry`\n\nQuery parameters:\n- granularity: String - Either \"year\" or \"month\" (defaults to \"year\")", "operationId": "getNumberOfPeopleRegisteredCompletionToStudyRegistry", "parameters": [ { "name": "granularity", "in": "query", "description": "Time granularity", "required": false, "schema": { "$ref": "#/components/schemas/TimeGranularity" } } ], "responses": { "200": { "description": "Study registry completion stats", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/GlobalStatEntry" } } } } } } } }, "/api/v0/main-frontend/global-stats/number-of-people-started-course": { "get": { "tags": ["global-stats"], "summary": "\nGET `/api/v0/main-frontend/global-stats/number-of-people-started-course`\n\nQuery parameters:\n- granularity: String - Either \"year\" or \"month\" (defaults to \"year\")", "operationId": "getNumberOfPeopleStartedCourse", "parameters": [ { "name": "granularity", "in": "query", "description": "Time granularity", "required": false, "schema": { "$ref": "#/components/schemas/TimeGranularity" } } ], "responses": { "200": { "description": "Course start stats", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/GlobalStatEntry" } } } } } } } }, "/api/v0/main-frontend/glossary/{term_id}": { "put": { "tags": ["glossary"], "operationId": "updateGlossaryTerm", "parameters": [ { "name": "term_id", "in": "path", "description": "Glossary term id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/TermUpdate" } } }, "required": true }, "responses": { "200": { "description": "Glossary term updated" }, "401": { "description": "Authentication required" }, "403": { "description": "User is not allowed to manage glossary terms" } } }, "delete": { "tags": ["glossary"], "operationId": "deleteGlossaryTerm", "parameters": [ { "name": "term_id", "in": "path", "description": "Glossary term id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Glossary term deleted" }, "401": { "description": "Authentication required" }, "403": { "description": "User is not allowed to manage glossary terms" } } } }, "/api/v0/main-frontend/oauth/.well-known/openid-configuration": { "get": { "tags": ["oauth"], "summary": "Handles `/.well-known/openid-configuration` to expose OIDC discovery metadata.", "description": "This endpoint advertises the AS/OP capabilities so clients can auto-configure:\n- Endpoints (authorize, token, userinfo, jwks)\n- Supported response/grant types\n- Token endpoint auth methods\n- ID Token signing algs\n- PKCE and DPoP metadata\n\nFollows:\n- [OIDC Discovery 1.0](https://openid.net/specs/openid-connect-discovery-1_0.html)\n- [RFC 8414 — OAuth 2.0 Authorization Server Metadata](https://www.rfc-editor.org/rfc/rfc8414)\n- [RFC 9449 — DPoP metadata](https://www.rfc-editor.org/rfc/rfc9449#name-authorization-server-metadata)\n\n# Example\n```http\nGET /api/v0/main-frontend/oauth/.well-known/openid-configuration HTTP/1.1\n```\n\nExample response (truncated):\n```json\n{\n \"issuer\": \"https://example.org/api/v0/main-frontend/oauth\",\n \"authorization_endpoint\": \"https://example.org/api/v0/main-frontend/oauth/authorize\",\n \"token_endpoint\": \"https://example.org/api/v0/main-frontend/oauth/token\",\n \"userinfo_endpoint\": \"https://example.org/api/v0/main-frontend/oauth/userinfo\",\n \"jwks_uri\": \"https://example.org/api/v0/main-frontend/oauth/jwks.json\",\n \"response_types_supported\": [\"code\"],\n \"grant_types_supported\": [\"authorization_code\",\"refresh_token\"],\n \"code_challenge_methods_supported\": [\"S256\"],\n \"token_endpoint_auth_methods_supported\": [\"none\",\"client_secret_post\"],\n \"id_token_signing_alg_values_supported\": [\"RS256\"],\n \"subject_types_supported\": [\"public\"],\n \"dpop_signing_alg_values_supported\": [\"ES256\",\"RS256\"]\n}\n```", "operationId": "getOauthOpenidConfiguration", "responses": { "200": { "description": "OAuth/OpenID Connect discovery document", "content": { "application/json": { "schema": {} } } } } } }, "/api/v0/main-frontend/oauth/authorize": { "get": { "tags": ["oauth"], "operationId": "authorizeOauthGet", "parameters": [ { "name": "response_type", "in": "query", "description": "OAuth response type", "required": false, "schema": { "type": "string" } }, { "name": "client_id", "in": "query", "description": "OAuth client id", "required": false, "schema": { "type": "string" } }, { "name": "redirect_uri", "in": "query", "description": "Redirect URI", "required": false, "schema": { "type": "string" } }, { "name": "scope", "in": "query", "description": "Requested scopes", "required": false, "schema": { "type": "string" } }, { "name": "state", "in": "query", "description": "OAuth state", "required": false, "schema": { "type": "string" } }, { "name": "nonce", "in": "query", "description": "OpenID Connect nonce", "required": false, "schema": { "type": "string" } }, { "name": "code_challenge", "in": "query", "description": "PKCE code challenge", "required": false, "schema": { "type": "string" } }, { "name": "code_challenge_method", "in": "query", "description": "PKCE code challenge method", "required": false, "schema": { "type": "string" } }, { "name": "prompt", "in": "query", "description": "Prompt behavior", "required": false, "schema": { "type": "string" } }, { "name": "request", "in": "query", "description": "Unsupported request object", "required": false, "schema": { "type": "string" } } ], "responses": { "302": { "description": "Redirect to login, consent, or client redirect URI" } } }, "post": { "tags": ["oauth"], "operationId": "authorizeOauthPost", "requestBody": { "content": { "application/x-www-form-urlencoded": { "schema": {} } }, "required": true }, "responses": { "302": { "description": "Redirect to login, consent, or client redirect URI" } } } }, "/api/v0/main-frontend/oauth/authorized-clients": { "get": { "tags": ["oauth"], "operationId": "getOauthAuthorizedClients", "responses": { "200": { "description": "Authorized OAuth clients", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/AuthorizedClientInfo" } } } } } } } }, "/api/v0/main-frontend/oauth/authorized-clients/{client_id}": { "delete": { "tags": ["oauth"], "operationId": "deleteOauthAuthorizedClient", "parameters": [ { "name": "client_id", "in": "path", "description": "OAuth client id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "204": { "description": "Authorized client revoked" } } } }, "/api/v0/main-frontend/oauth/consent": { "post": { "tags": ["oauth"], "summary": "Handles `/consent` approval after the user agrees to grant requested scopes.", "description": "This endpoint:\n- Validates the redirect URI and requested scopes against the registered client.\n- Records granted scopes for the user-client pair.\n- Redirects back to `/authorize` to continue the OAuth flow.\n\n# Example\n```http\nGET /api/v0/main-frontend/oauth/consent?client_id=test-client-id&redirect_uri=http://localhost&scopes=openid%20profile&state=random123&nonce=secure_nonce_abc HTTP/1.1\nCookie: session=abc123\n\n```\n\nRedirect back to `/authorize`:\n```http\nHTTP/1.1 302 Found\nLocation: /api/v0/main-frontend/oauth/authorize?client_id=...\n```", "operationId": "approveOauthConsent", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConsentQuery" } } }, "required": true }, "responses": { "200": { "description": "Consent approval response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConsentResponse" } } } } } } }, "/api/v0/main-frontend/oauth/consent/deny": { "post": { "tags": ["oauth"], "summary": "Handles `/consent/deny` when the user refuses to grant scopes.", "description": "This endpoint:\n- Redirects back to the client with `error=access_denied`.\n\n# Example\n```http\nGET /api/v0/main-frontend/oauth/consent/deny?redirect_uri=http://localhost&state=random123 HTTP/1.1\n\n```\n\nResponse:\n```http\nHTTP/1.1 302 Found\nLocation: http://localhost?error=access_denied&state=random123\n```", "operationId": "denyOauthConsent", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConsentDenyQuery" } } }, "required": true }, "responses": { "200": { "description": "Consent denial response", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConsentResponse" } } } } } } }, "/api/v0/main-frontend/oauth/introspect": { "post": { "tags": ["oauth"], "summary": "Handles the `/introspect` endpoint for OAuth 2.0 token introspection (RFC 7662).", "description": "This endpoint allows resource servers to query the authorization server about\nthe active state and metadata of an access token.\n\n### Security Features\n- Client authentication is required (client_id and client_secret for confidential clients)\n- Returns `active: false` for invalid/expired tokens or authentication failures\n to prevent token enumeration attacks\n- Always returns 200 OK, even for invalid tokens (per RFC 7662)\n\n### Request Parameters\n- `token` (required): The token to be introspected\n- `token_type_hint` (optional): Hint about token type (\"access_token\" or \"refresh_token\")\n- `client_id` (required): Client identifier\n- `client_secret` (required for confidential clients): Client secret\n\n### Response\nReturns a JSON object with:\n- `active` (bool, required): Whether the token is active\n- Additional fields only present if `active: true`:\n - `scope`: Space-separated list of scopes\n - `client_id`: Client identifier\n - `username`/`sub`: User identifier (if token has user)\n - `exp`: Expiration timestamp (Unix time)\n - `iat`: Issued at timestamp (Unix time)\n - `aud`: Audience\n - `iss`: Issuer\n - `jti`: JWT ID\n - `token_type`: \"Bearer\" or \"DPoP\"\n\nFollows [RFC 7662 — OAuth 2.0 Token Introspection](https://datatracker.ietf.org/doc/html/rfc7662).\n\n# Example\n```http\nPOST /api/v0/main-frontend/oauth/introspect HTTP/1.1\nContent-Type: application/x-www-form-urlencoded\n\ntoken=ACCESS_TOKEN&client_id=test-client-id&client_secret=test-secret\n```\n\nSuccessful response:\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\nCache-Control: no-store\n\n{\n \"active\": true,\n \"scope\": \"openid profile email\",\n \"client_id\": \"test-client-id\",\n \"sub\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"username\": \"550e8400-e29b-41d4-a716-446655440000\",\n \"exp\": 1735689600,\n \"iat\": 1735686000,\n \"iss\": \"https://example.com/api/v0/main-frontend/oauth\",\n \"jti\": \"123e4567-e89b-12d3-a456-426614174000\",\n \"token_type\": \"Bearer\"\n}\n```\n\nInactive token response:\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\nCache-Control: no-store\n\n{\n \"active\": false\n}\n```", "operationId": "introspectOauthToken", "requestBody": { "content": { "application/x-www-form-urlencoded": { "schema": {} } }, "required": true }, "responses": { "200": { "description": "OAuth token introspection response", "content": { "application/json": { "schema": {} } } } } } }, "/api/v0/main-frontend/oauth/jwks.json": { "get": { "tags": ["oauth"], "summary": "Handles `/jwks.json` for returning the JSON Web Key Set (JWKS).", "description": "This endpoint:\n- Reads the configured ID Token signing public key (RS256).\n- Exposes it in JWKS format for clients to validate ID tokens.\n\nFollows [RFC 7517](https://datatracker.ietf.org/doc/html/rfc7517).\n\nNote: Currently exposes a single signing key. Key rotation (OIDC Core §10) is not implemented.\n\n# Example\n```http\nGET /api/v0/main-frontend/oauth/jwks.json HTTP/1.1\n```\n\nResponse:\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"keys\": [\n { \"kty\":\"RSA\",\"use\":\"sig\",\"alg\":\"RS256\",\"kid\":\"abc123\",\"n\":\"...\",\"e\":\"AQAB\" }\n ]\n}\n```", "operationId": "getOauthJwks", "responses": { "200": { "description": "OAuth JSON Web Key Set", "content": { "application/json": { "schema": {} } } } } } }, "/api/v0/main-frontend/oauth/revoke": { "post": { "tags": ["oauth"], "summary": "Handles the `/revoke` endpoint for OAuth 2.0 token revocation (RFC 7009).", "description": "This endpoint allows clients to revoke access tokens or refresh tokens.\n\n### Security Features\n- Client authentication is required (client_id and client_secret)\n- Always returns `200 OK` even for invalid/expired/already-revoked tokens\n to prevent token enumeration attacks\n- Validates that the token belongs to the authenticated client before revoking\n\n### Request Parameters\n- `token` (required): The token to be revoked\n- `token_type_hint` (optional): Hint about token type (\"access_token\" or \"refresh_token\")\n\nFollows [RFC 7009 — OAuth 2.0 Token Revocation](https://datatracker.ietf.org/doc/html/rfc7009).\n\n# Example\n```http\nPOST /api/v0/main-frontend/oauth/revoke HTTP/1.1\nContent-Type: application/x-www-form-urlencoded\n\ntoken=ACCESS_TOKEN_TO_REVOKE&token_type_hint=access_token&client_id=test-client-id&client_secret=test-secret\n```\n\nResponse (always 200 OK):\n```http\nHTTP/1.1 200 OK\n```", "operationId": "revokeOauthToken", "requestBody": { "content": { "application/x-www-form-urlencoded": { "schema": {} } }, "required": true }, "responses": { "200": { "description": "OAuth token revocation acknowledged" } } } }, "/api/v0/main-frontend/oauth/token": { "post": { "tags": ["oauth"], "summary": "Handles the `/token` endpoint for exchanging authorization codes or refresh tokens.", "description": "This endpoint issues and rotates OAuth 2.0 and OpenID Connect tokens with support for\n**PKCE**, **DPoP sender-constrained tokens**, and **ID Token issuance**.\n\n### Authorization Code Grant\n- Validates client credentials (`client_id`, `client_secret`) or public client rules.\n- Verifies the authorization code, its redirect URI, PKCE binding (`code_verifier`), and expiration.\n- Optionally verifies a DPoP proof and binds the issued tokens to the DPoP JWK thumbprint (`dpop_jkt`).\n- Issues a new access token, refresh token, and (for OIDC requests) an ID token.\n\n### Refresh Token Grant\n- Validates the refresh token and client binding.\n- Verifies DPoP proof when applicable (must match the original `dpop_jkt`).\n- Rotates the refresh token (revokes the old one, inserts a new one linked to it).\n- Issues a new access token (and ID token if `openid` scope requested).\n\n### Security Features\n- **PKCE (RFC 7636)**: Enforced for public clients and optionally for confidential ones.\n- **DPoP (RFC 9449)**: Sender-constrains tokens to a JWK thumbprint.\n- **Refresh Token Rotation**: Prevents replay by revoking old RTs on use.\n- **OIDC ID Token**: Issued only if `openid` is in the granted scopes.\n\nFollows:\n- [RFC 6749 §3.2 — Token Endpoint](https://datatracker.ietf.org/doc/html/rfc6749#section-3.2)\n- [RFC 7636 — PKCE](https://datatracker.ietf.org/doc/html/rfc7636)\n- [RFC 9449 — DPoP](https://datatracker.ietf.org/doc/html/rfc9449)\n- [OIDC Core §3.1.3 — Token Endpoint](https://openid.net/specs/openid-connect-core-1_0.html#TokenEndpoint)\n\n# Example\n```http\nPOST /api/v0/main-frontend/oauth/token HTTP/1.1\nContent-Type: application/x-www-form-urlencoded\n\ngrant_type=authorization_code&code=SplxlOBeZQQYbYS6WxSbIA&redirect_uri=http://localhost&client_id=test-client-id&client_secret=test-secret&code_verifier=dBjftJeZ4CVP-mB92K27uhbUJU1p1r_wW1gFWFOEjXk\n```\n\nSuccessful response:\n```http\nHTTP/1.1 200 OK\nContent-Type: application/json\n\n{\n \"access_token\": \"2YotnFZFEjr1zCsicMWpAA\",\n \"refresh_token\": \"tGzv3JOkF0XG5Qx2TlKWIA\",\n \"id_token\": \"eyJhbGciOiJSUzI1NiIsInR5cCI6IkpXVCJ9...\",\n \"token_type\": \"DPoP\",\n \"expires_in\": 3600\n}\n```\n\nExample error:\n```http\nHTTP/1.1 401 Unauthorized\nContent-Type: application/json\n\n{\n \"error\": \"invalid_client\",\n \"error_description\": \"invalid client secret\"\n}\n```\n\nExample DPoP error:\n```http\nHTTP/1.1 401 Unauthorized\nWWW-Authenticate: DPoP error=\"use_dpop_proof\", error_description=\"Missing DPoP header\"\n```", "operationId": "exchangeOauthToken", "requestBody": { "content": { "application/x-www-form-urlencoded": { "schema": {} } }, "required": true }, "responses": { "200": { "description": "OAuth token response", "content": { "application/json": { "schema": {} } } }, "401": { "description": "OAuth token error" } } } }, "/api/v0/main-frontend/oauth/userinfo": { "get": { "tags": ["oauth"], "operationId": "getOauthUserInfo", "responses": { "200": { "description": "OAuth userinfo response", "content": { "application/json": { "schema": {} } } }, "401": { "description": "Invalid token" } } }, "post": { "tags": ["oauth"], "operationId": "postOauthUserInfo", "responses": { "200": { "description": "OAuth userinfo response", "content": { "application/json": { "schema": {} } } }, "401": { "description": "Invalid token" } } } }, "/api/v0/main-frontend/org/{organization_slug}": { "get": { "tags": ["org"], "summary": "\nGET `/api/v0/main-frontend/org/:slug", "operationId": "getOrganizationBySlug", "parameters": [ { "name": "organization_slug", "in": "path", "description": "Organization slug", "required": true, "schema": { "type": "string" } } ], "responses": { "200": { "description": "Organization", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Organization" } } } } } } }, "/api/v0/main-frontend/organizations": { "get": { "tags": ["organizations"], "summary": "\nGET `/api/v0/main-frontend/organizations` - Returns a list of all organizations.", "operationId": "getOrganizations", "responses": { "200": { "description": "Organizations", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Organization" } } } } } } }, "post": { "tags": ["organizations"], "summary": "POST `/api/v0/main-frontend/organizations`\nCreates a new organization with the given name, slug, and visibility status.", "description": "# Request body (JSON)\n{\n \"name\": \"Example Organization\",\n \"slug\": \"example-org\",\n \"hidden\": false\n}\n\n# Response\nReturns the created organization.\n\n# Permissions\nOnly users with the `Admin` role can access this endpoint.", "operationId": "createOrganization", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrganizationCreatePayload" } } }, "required": true }, "responses": { "200": { "description": "Created organization", "content": { "application/json": { "schema": {} } } } } } }, "/api/v0/main-frontend/organizations/{exam_id}/fetch_org_exam": { "get": { "tags": ["organizations"], "summary": "\nGET `/api/v0/main-frontend/organizations/{exam_id}/fetch_org_exam", "operationId": "getOrganizationExamByExamId", "parameters": [ { "name": "exam_id", "in": "path", "description": "Exam id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Organization exam", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrgExam" } } } } } } }, "/api/v0/main-frontend/organizations/{organization_id}": { "get": { "tags": ["organizations"], "summary": "\nGET `/api/v0/main-frontend/organizations/{organization_id}` - Returns an organizations with id.", "operationId": "getOrganization", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Organization", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Organization" } } } } } }, "put": { "tags": ["organizations"], "summary": "\nPUT `/api/v0/main-frontend/organizations/{organization_id}`\n\nUpdates an organization's name, hidden status, and slug.", "operationId": "updateOrganization", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/OrganizationUpdatePayload" } } }, "required": true }, "responses": { "200": { "description": "Organization updated" } } }, "patch": { "tags": ["organizations"], "operationId": "softDeleteOrganization", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Organization soft deleted" } } } }, "/api/v0/main-frontend/organizations/{organization_id}/course_exams": { "get": { "tags": ["organizations"], "summary": "\nGET `/api/v0/main-frontend/organizations/{organization_id}/course_exams` - Returns an organizations exams in CourseExam form.", "operationId": "getOrganizationCourseExams", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Organization course exams", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CourseExam" } } } } } } } }, "/api/v0/main-frontend/organizations/{organization_id}/courses": { "get": { "tags": ["organizations"], "summary": "\nGET `/api/v0/main-frontend/organizations/{organization_id}/courses\"` - Returns a list of all courses in a organization.", "operationId": "getOrganizationCourses", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Organization courses", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Course" } } } } } } } }, "/api/v0/main-frontend/organizations/{organization_id}/courses/active": { "get": { "tags": ["organizations"], "operationId": "getOrganizationActiveCourses", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Active organization courses", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Course" } } } } } } } }, "/api/v0/main-frontend/organizations/{organization_id}/courses/active/count": { "get": { "tags": ["organizations"], "operationId": "getOrganizationActiveCourseCount", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Active organization course count", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseCount" } } } } } } }, "/api/v0/main-frontend/organizations/{organization_id}/courses/count": { "get": { "tags": ["organizations"], "operationId": "getOrganizationCourseCount", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Organization course count", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseCount" } } } } } } }, "/api/v0/main-frontend/organizations/{organization_id}/courses/duplicatable": { "get": { "tags": ["organizations"], "summary": "\nGET `/api/v0/main-frontend/organizations/{organization_id}/courses/duplicatable\"` - Returns a list of all courses in a organization that the current user has permission to duplicate.", "operationId": "getOrganizationDuplicatableCourses", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Duplicatable organization courses", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Course" } } } } } } } }, "/api/v0/main-frontend/organizations/{organization_id}/exams": { "post": { "tags": ["organizations"], "summary": "\nPOST `/api/v0/main-frontend/organizations/{organization_id}/exams` - Creates new exam for the organization.", "operationId": "createOrganizationExam", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewExam" } } }, "required": true }, "responses": { "200": { "description": "Organization exam created" } } } }, "/api/v0/main-frontend/organizations/{organization_id}/image": { "put": { "tags": ["organizations"], "summary": "\nPUT `/api/v0/main-frontend/organizations/:organizations_id/image` - Sets or updates the chapter image.\n\n# Example\n\nRequest:\n```http\nPUT /api/v0/main-frontend/organizations/d332f3d9-39a5-4a18-80f4-251727693c37/image HTTP/1.1\nContent-Type: multipart/form-data\n\nBINARY_DATA\n```", "operationId": "updateOrganizationImage", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "required": ["file"], "properties": { "file": { "type": "string", "format": "binary", "contentMediaType": "application/octet-stream" } } } } }, "required": true }, "responses": { "200": { "description": "Updated organization", "content": { "application/json": { "schema": {} } } } } }, "delete": { "tags": ["organizations"], "summary": "\nDELETE `/api/v0/main-frontend/organizations/:organizations_id/image` - Removes the organizations image.\n\n# Example\n\nRequest:\n```http\nDELETE /api/v0/main-frontend/organizations/d332f3d9-39a5-4a18-80f4-251727693c37/image HTTP/1.1\n```", "operationId": "deleteOrganizationImage", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Organization image removed" } } } }, "/api/v0/main-frontend/organizations/{organization_id}/org_exams": { "get": { "tags": ["organizations"], "summary": "\nGET `/api/v0/main-frontend/organizations/{organization_id}/exams` - Returns an organizations exams in Exam form.", "operationId": "getOrganizationExams", "parameters": [ { "name": "organization_id", "in": "path", "description": "Organization id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Organization exams", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/OrgExam" } } } } } } } }, "/api/v0/main-frontend/page_audio/{file_id}": { "delete": { "tags": ["page_audio"], "summary": "\nDELETE `/api/v0/main-frontend/page_audio/:file_id` - Removes the chapter image.\n\n# Example\n\nRequest:\n```http\nDELETE /api/v0/main-frontend/page_audio/d332f3d9-39a5-4a18-80f4-251727693c37 HTTP/1.1\n```", "operationId": "deletePageAudioFile", "parameters": [ { "name": "file_id", "in": "path", "description": "Page audio file id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Page audio deleted" } } } }, "/api/v0/main-frontend/page_audio/{page_id}": { "post": { "tags": ["page_audio"], "summary": "\nPOST `/api/v0/main-frontend/page_audio/:page_id` - Sets or updates the page audio.\n\n# Example\n\nRequest:\n```http\nPOST /api/v0/main-frontend/page_audio/d332f3d9-39a5-4a18-80f4-251727693c37 HTTP/1.1\nContent-Type: multipart/form-data\n\nBINARY_DATA\n```", "operationId": "createPageAudioFile", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "multipart/form-data": { "schema": { "type": "object", "required": ["file"], "properties": { "file": { "type": "array", "items": { "type": "integer", "format": "int32", "minimum": 0 }, "contentMediaType": "application/octet-stream" } } } } }, "required": true }, "responses": { "200": { "description": "Page audio uploaded", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/page_audio/{page_id}/files": { "get": { "tags": ["page_audio"], "summary": "\nGET `/api/v0/main-fronted/page_audio/:page_id/files` - Get a page audio files\n\nRequest: `GET /api/v0/cms/page_audio/40ca9bcf-8eaa-41ba-940e-0fd5dd0c3c02/files`", "operationId": "getPageAudioFiles", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Page audio files", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PageAudioFile" } } } } } } } }, "/api/v0/main-frontend/pages": { "post": { "tags": ["pages"], "summary": "\nPOST `/api/v0/main-frontend/pages` - Create a new page.\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:\n\nRequest:\n```http\nPOST /api/v0/main-frontend/pages HTTP/1.1\nContent-Type: application/json\n\n{\n \"content\": [\n {\n \"type\": \"x\",\n \"id\": \"2a4e517d-a7d2-4d82-89fb-a1333d8d01d1\"\n }\n ],\n \"url_path\": \"/part-2/best-page\",\n \"title\": \"Hello world!\",\n \"course_id\": \"10363c5b-82b4-4121-8ef1-bae8fb42a5ce\",\n \"chapter_id\": \"2495ffa3-7ea9-4615-baa5-828023688c79\"\n}\n```", "operationId": "createPage", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewPage" } } }, "required": true }, "responses": { "200": { "description": "Created page", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Page" } } } } } } }, "/api/v0/main-frontend/pages/{course_id}/all-course-pages-for-course": { "get": { "tags": ["pages"], "summary": "\nGET `/api/v0/main-frontend/pages/:course_id/all-course-pages-for-course` - Get all pages of a course", "operationId": "getCoursePages", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course pages", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Page" } } } } } } } }, "/api/v0/main-frontend/pages/{page_id}": { "delete": { "tags": ["pages"], "summary": "\nDELETE `/api/v0/main-frontend/pages/:page_id` - Delete a page, related exercises, and related exercise tasks by id.\n\n\n# Example\n\nRequest: `DELETE /api/v0/main-frontend/pages/40ca9bcf-8eaa-41ba-940e-0fd5dd0c3c02`", "operationId": "deletePage", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted page", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/Page" } } } } } } }, "/api/v0/main-frontend/pages/{page_id}/history": { "get": { "tags": ["pages"], "summary": "\nGET /api/v0/main-frontend/pages/:page_id/history", "operationId": "getPageHistory", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Page history entries", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PageHistory" } } } } } } } }, "/api/v0/main-frontend/pages/{page_id}/history_count": { "get": { "tags": ["pages"], "summary": "\nGET /api/v0/main-frontend/pages/:page_id/history_count", "operationId": "getPageHistoryCount", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Page history count", "content": { "text/plain": { "schema": { "type": "integer", "format": "int64" } } } } } } }, "/api/v0/main-frontend/pages/{page_id}/info": { "get": { "tags": ["pages"], "summary": "\nGET `/api/v0/main-fronted/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": "getPageInfo", "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/main-frontend/pages/{page_id}/page-details": { "put": { "tags": ["pages"], "summary": "\nPOST `/api/v0/main-frontend/pages/:page_id/page-details` - Update pages title and url_path.", "operationId": "updatePageDetails", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PageDetailsUpdate" } } }, "required": true }, "responses": { "200": { "description": "Updated page details", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/pages/{page_id}/restore": { "post": { "tags": ["pages"], "summary": "\nPOST /api/v0/main-frontend/pages/:page_id/restore", "operationId": "restorePageHistory", "parameters": [ { "name": "page_id", "in": "path", "description": "Page id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/HistoryRestoreData" } } }, "required": true }, "responses": { "200": { "description": "Restored history id", "content": { "text/plain": { "schema": { "type": "string", "format": "uuid" } } } } } } }, "/api/v0/main-frontend/playground-views/grading/{websocket_id}": { "post": { "tags": ["playground-views"], "summary": "playground-views passes a URL pointing to this route to an exercise service when sending submissions so that if\nthe service has an update for a pending grading, it will be sent here and passed on to through the websocket", "operationId": "receivePlaygroundGrading", "parameters": [ { "name": "websocket_id", "in": "path", "description": "Playground websocket id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ExerciseTaskGradingResult" } } }, "required": true }, "responses": { "200": { "description": "Grading forwarded to websocket client" } } } }, "/api/v0/main-frontend/playground-views/ws": { "get": { "tags": ["playground-views"], "summary": "Starts a new websocket connection.", "operationId": "getPlaygroundViewsWebsocket", "responses": { "101": { "description": "WebSocket connection upgraded" } } } }, "/api/v0/main-frontend/playground_examples": { "get": { "tags": ["playground-examples"], "summary": "\nGET `/api/v0/main-frontend/playground_examples` - Returns all playground examples that are not deleted.", "operationId": "getPlaygroundExamples", "responses": { "200": { "description": "Playground examples", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PlaygroundExample" } } } } } } }, "put": { "tags": ["playground-examples"], "summary": "\nPUT `/api/v0/main-frontend/playground_examples` - Updates existing playground example.", "operationId": "updatePlaygroundExample", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlaygroundExample" } } }, "required": true }, "responses": { "200": { "description": "Updated playground example", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlaygroundExample" } } } } } }, "post": { "tags": ["playground-examples"], "summary": "\nPOST `/api/v0/main-frontend/playground_examples` - Saves a playground example.", "operationId": "createPlaygroundExample", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlaygroundExampleData" } } }, "required": true }, "responses": { "200": { "description": "Created playground example", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlaygroundExample" } } } } } } }, "/api/v0/main-frontend/playground_examples/{playground_example_id}": { "delete": { "tags": ["playground-examples"], "summary": "\nDELETE `/api/v0/main-frontend/playground_examples` - Deletes a playground example if exists.", "operationId": "deletePlaygroundExample", "parameters": [ { "name": "playground_example_id", "in": "path", "description": "Playground example id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Deleted playground example", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/PlaygroundExample" } } } } } } }, "/api/v0/main-frontend/proposed-edits/course/{course_id}": { "get": { "tags": ["proposed_edits"], "summary": "\nGET `/api/v0/main-frontend/proposed-edits/course/:id?pending=true` - Returns feedback for the given course.", "operationId": "getEditProposals", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "pending", "in": "query", "description": "Whether to fetch pending proposals", "required": true, "schema": { "type": "boolean" } }, { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Edit proposals", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PageProposal" } } } } } } } }, "/api/v0/main-frontend/proposed-edits/course/{course_id}/count": { "get": { "tags": ["proposed_edits"], "summary": "\nGET `/api/v0/main-frontend/proposed-edits/course/:id/count` - Returns the amount of feedback for the given course.", "operationId": "getEditProposalCount", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Edit proposal counts", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ProposalCount" } } } } } } }, "/api/v0/main-frontend/proposed-edits/process-edit-proposal": { "post": { "tags": ["proposed_edits"], "summary": "\nPOST `/api/v0/main-frontend/proposed-edits/process-edit-proposal` - Processes the given edit proposal.", "operationId": "processEditProposal", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EditProposalInfo" } } }, "required": true }, "responses": { "200": { "description": "Processed edit proposal" } } } }, "/api/v0/main-frontend/regradings": { "get": { "tags": ["regradings"], "summary": "\nGET `/api/v0/main-frontend/regradings` - Returns a paginated list of all the regradings.", "operationId": "getRegradings", "parameters": [ { "name": "page", "in": "query", "description": "Page number", "required": false, "schema": { "type": "integer", "format": "int64" } }, { "name": "limit", "in": "query", "description": "Page size", "required": false, "schema": { "type": "integer", "format": "int64" } } ], "responses": { "200": { "description": "Regradings", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Regrading" } } } } } } }, "post": { "tags": ["regradings"], "summary": "\nPOST `/api/v0/main-frontend/regradings` - Creates a new regrading for the supplied exercise task submission ids and returns the new regrading id.", "operationId": "createRegrading", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewRegrading" } } }, "required": true }, "responses": { "200": { "description": "Created regrading id", "content": { "text/plain": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/regradings/count": { "get": { "tags": ["regradings"], "summary": "\nGET `/api/v0/main-frontend/regradings/count` - Counts regradings", "operationId": "getRegradingsCount", "responses": { "200": { "description": "Regradings count", "content": { "text/plain": { "schema": { "type": "integer", "format": "int64" } } } } } } }, "/api/v0/main-frontend/regradings/{regrading_id}": { "get": { "tags": ["regradings"], "summary": "\nGET `/api/v0/main-frontend/regradings/{id}` - Returns relevant information about a regrading.", "operationId": "getRegradingInfo", "parameters": [ { "name": "regrading_id", "in": "path", "description": "Regrading id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Regrading info", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RegradingInfo" } } } } } } }, "/api/v0/main-frontend/roles": { "get": { "tags": ["roles"], "summary": "\n * GET /api/v0/main-frontend/roles - Get all roles for the given domain.", "operationId": "getRoles", "parameters": [ { "name": "global", "in": "query", "description": "Global domain", "required": false, "schema": { "type": "boolean" } }, { "name": "organization_id", "in": "query", "description": "Organization id", "required": false, "schema": { "type": "string", "format": "uuid" } }, { "name": "course_id", "in": "query", "description": "Course id", "required": false, "schema": { "type": "string", "format": "uuid" } }, { "name": "course_instance_id", "in": "query", "description": "Course instance id", "required": false, "schema": { "type": "string", "format": "uuid" } }, { "name": "exam_id", "in": "query", "description": "Exam id", "required": false, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Roles", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/RoleUser" } } } } } } } }, "/api/v0/main-frontend/roles/add": { "post": { "tags": ["roles"], "summary": "\n * POST /api/v0/main-frontend/roles/add - Give a role to a user.", "operationId": "addRole", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoleInfo" } } }, "required": true }, "responses": { "200": { "description": "Role added" } } } }, "/api/v0/main-frontend/roles/pending": { "get": { "tags": ["roles"], "summary": "\n * GET /api/v0/main-frontend/roles - Get all pending roles for the given domain.", "operationId": "getPendingRoles", "parameters": [ { "name": "global", "in": "query", "description": "Global domain", "required": false, "schema": { "type": "boolean" } }, { "name": "organization_id", "in": "query", "description": "Organization id", "required": false, "schema": { "type": "string", "format": "uuid" } }, { "name": "course_id", "in": "query", "description": "Course id", "required": false, "schema": { "type": "string", "format": "uuid" } }, { "name": "course_instance_id", "in": "query", "description": "Course instance id", "required": false, "schema": { "type": "string", "format": "uuid" } }, { "name": "exam_id", "in": "query", "description": "Exam id", "required": false, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Pending roles", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PendingRole" } } } } } } } }, "/api/v0/main-frontend/roles/remove": { "post": { "tags": ["roles"], "summary": "\n * POST /api/v0/main-frontend/roles/remove - Remove a role from a user.", "operationId": "removeRole", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/RoleInfo" } } }, "required": true }, "responses": { "200": { "description": "Role removed" } } } }, "/api/v0/main-frontend/status/cronjobs": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/cronjobs`\n\nReturns the status of all CronJobs in the current namespace.", "operationId": "getStatusCronjobs", "responses": { "200": { "description": "Cronjobs", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/CronJobInfo" } } } } } } } }, "/api/v0/main-frontend/status/deployments": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/deployments`\n\nReturns the status of all Deployments in the current namespace.", "operationId": "getStatusDeployments", "responses": { "200": { "description": "Deployments", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/DeploymentInfo" } } } } } } } }, "/api/v0/main-frontend/status/events": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/events`\n\nReturns the status of all Events in the current namespace.", "operationId": "getStatusEvents", "responses": { "200": { "description": "Events", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/EventInfo" } } } } } } } }, "/api/v0/main-frontend/status/health": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/health`\n\nReturns detailed system health status with issues list (admin only).", "operationId": "getStatusHealth", "responses": { "200": { "description": "Detailed system health", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SystemHealthStatus" } } } } } } }, "/api/v0/main-frontend/status/ingresses": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/ingresses`\n\nReturns the status of all Ingresses in the current namespace.", "operationId": "getStatusIngresses", "responses": { "200": { "description": "Ingresses", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/IngressInfo" } } } } } } } }, "/api/v0/main-frontend/status/jobs": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/jobs`\n\nReturns the status of all Jobs in the current namespace.", "operationId": "getStatusJobs", "responses": { "200": { "description": "Jobs", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/JobInfo" } } } } } } } }, "/api/v0/main-frontend/status/pod-disruption-budgets": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/pod-disruption-budgets`\n\nReturns the status of all PodDisruptionBudgets in the current namespace.", "operationId": "getStatusPodDisruptionBudgets", "responses": { "200": { "description": "Pod disruption budgets", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PodDisruptionBudgetInfo" } } } } } } } }, "/api/v0/main-frontend/status/pods": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/pods`\n\nReturns the status of all Pods in the current namespace.", "operationId": "getStatusPods", "responses": { "200": { "description": "Pods", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/PodInfo" } } } } } } } }, "/api/v0/main-frontend/status/pods/{pod_name}/logs": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/pods/{pod_name}/logs`\n\nReturns logs from a specific pod.\n\nQuery parameters:\n- container: Optional - Container name (if pod has multiple containers)\n- tail: Optional - Number of lines to tail from the end (default: 1000, max: 10000)", "operationId": "getStatusPodLogs", "parameters": [ { "name": "pod_name", "in": "path", "description": "Pod name", "required": true, "schema": { "type": "string" } }, { "name": "container", "in": "query", "description": "Container name", "required": false, "schema": { "type": "string" } }, { "name": "tail", "in": "query", "description": "Number of log lines", "required": false, "schema": { "type": "integer", "format": "int64", "minimum": 0 } } ], "responses": { "200": { "description": "Pod logs", "content": { "text/plain": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/status/services": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/services`\n\nReturns the status of all Services in the current namespace.", "operationId": "getStatusServices", "responses": { "200": { "description": "Services", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ServiceInfo" } } } } } } } }, "/api/v0/main-frontend/status/system-health": { "get": { "tags": ["status"], "summary": "\nGET `/api/v0/main-frontend/status/system-health` Returns a boolean indicating whether the system is healthy.\n\nUses the same underlying checking logic as the detailed health endpoint.\nUnauthenticated users get a boolean. Authenticated admins get error details on failure.", "operationId": "getStatusSystemHealth", "responses": { "200": { "description": "System health", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/teacher-grading-decisions": { "post": { "tags": ["teacher_grading_decisions"], "summary": "\nPOST `/api/v0/main-frontend/teacher-grading-decisions` - Creates a new teacher grading decision, overriding the points a user has received from an exercise.", "operationId": "createTeacherGradingDecision", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/NewTeacherGradingDecision" } } }, "required": true }, "responses": { "200": { "description": "Teacher grading decision created", "content": { "application/json": { "schema": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/UserExerciseState" } ] } } } } } } }, "/api/v0/main-frontend/time": { "get": { "tags": ["time"], "summary": "\nGET `/api/v0/main-frontend/time` Returns the server's current UTC time as an RFC3339 timestamp string.\n\nResponse body example:\n`\"2026-02-18T12:34:56.789Z\"`", "operationId": "getCurrentTime", "responses": { "200": { "description": "Current server time", "content": { "text/plain": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/user-details/bulk-user-details": { "post": { "tags": ["user-details"], "summary": "\nPOST `/api/v0/main-frontend/user-details/bulk-user-details` - Get user details for a list of user IDs with course permission check\nOnly returns user details for users who are actually enrolled in the specified course", "operationId": "getBulkUserDetails", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/BulkUserDetailsRequest" } } }, "required": true }, "responses": { "200": { "description": "Bulk user details", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserDetail" } } } } } } } }, "/api/v0/main-frontend/user-details/search-by-email": { "post": { "tags": ["user-details"], "summary": "\nGET `/api/v0/main-frontend/user-details/search-by-email` - Allows to search user by their email", "operationId": "searchUserDetailsByEmail", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchRequest" } } }, "required": true }, "responses": { "200": { "description": "User details search results", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserDetail" } } } } } } } }, "/api/v0/main-frontend/user-details/search-by-other-details": { "post": { "tags": ["user-details"], "summary": "\nGET `/api/v0/main-frontend/user-details/search-by-other-details` - Allows to search user by their names etc.", "operationId": "searchUserDetailsByOtherDetails", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchRequest" } } }, "required": true }, "responses": { "200": { "description": "User details search results", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserDetail" } } } } } } } }, "/api/v0/main-frontend/user-details/search-fuzzy-match": { "post": { "tags": ["user-details"], "summary": "\nGET `/api/v0/main-frontend/user-details/search-fuzzy-match` - Allows to find the right user details in cases where there is a small typing error in the search query", "operationId": "searchUserDetailsFuzzyMatch", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/SearchRequest" } } }, "required": true }, "responses": { "200": { "description": "User details fuzzy search results", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserDetail" } } } } } } } }, "/api/v0/main-frontend/user-details/update-user-info": { "post": { "tags": ["user-details"], "summary": "\nPOST `/api/v0/main-frontend/user-details/update-user-info` - Updates the users information such as email, name, country and email communication consent", "operationId": "updateUserInfo", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserInfoPayload" } } }, "required": true }, "responses": { "200": { "description": "Updated user details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDetail" } } } } } } }, "/api/v0/main-frontend/user-details/user-by-courses": { "post": { "tags": ["user-details"], "summary": "\nPOST `/api/v0/main-frontend/user-details/user-by-courses` - Find user details by user id with multi-course permission check\nReturns user details if the user has permission to view user details through any of the specified courses", "operationId": "getUserDetailsByCourses", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDetailsRequest" } } }, "required": true }, "responses": { "200": { "description": "User details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDetail" } } } }, "403": { "description": "Forbidden", "content": { "application/json": { "schema": {} } } }, "404": { "description": "User details not found", "content": { "application/json": { "schema": {} } } }, "500": { "description": "Internal server error", "content": { "application/json": { "schema": {} } } } } } }, "/api/v0/main-frontend/user-details/user-details-for-user": { "get": { "tags": ["user-details"], "summary": "\nGET `/api/v0/main-frontend/user-details/user-details-for-user` - Get authenticated user's own details", "operationId": "getUserDetailsForAuthenticatedUser", "responses": { "200": { "description": "Authenticated user details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDetail" } } } } } } }, "/api/v0/main-frontend/user-details/users-ip-country": { "get": { "tags": ["user-details"], "operationId": "getUsersIpCountry", "responses": { "200": { "description": "Country inferred from request IP", "content": { "text/plain": { "schema": { "type": "string" } } } } } } }, "/api/v0/main-frontend/user-details/{course_id}/get-users-by-course-id": { "get": { "tags": ["user-details"], "summary": "\nGET `/api/v0/main-frontend/user-details/get-users-by-course-id` - Get user details of users that are in the course", "operationId": "getUsersByCourseIdForUserDetails", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Users by course id", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserDetail" } } } } } } } }, "/api/v0/main-frontend/user-details/{course_id}/user/{user_id}": { "get": { "tags": ["user-details"], "summary": "\nGET `/api/v0/main-frontend/user-details/{course_id}/user/{user_id}` - Find user details by user id with course permission check\nOnly returns user details if the user is enrolled in the specified course", "operationId": "getUserDetailsByCourseAndUserId", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User details", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserDetail" } } } } } } }, "/api/v0/main-frontend/users/change-password": { "post": { "tags": ["users"], "operationId": "changeUserPassword", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ChangePasswordData" } } }, "required": true }, "responses": { "200": { "description": "Password change status", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/users/get-user-research-consent": { "get": { "tags": ["users"], "summary": "\nGET `/api/v0/main-frontend/users/get-user-research-consent` - Gets users research consent.", "operationId": "getUserResearchConsent", "responses": { "200": { "description": "User research consent", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserResearchConsent" } } } } } } }, "/api/v0/main-frontend/users/my-courses": { "get": { "tags": ["users"], "summary": "\nGET `/api/v0/main-frontend/users/my-courses` - Gets all the courses the user has either started or gotten a permission to.", "operationId": "getMyCourses", "responses": { "200": { "description": "Courses for authenticated user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/MyCourse" } } } } } } } }, "/api/v0/main-frontend/users/my-courses/{course_id}/hide": { "post": { "tags": ["users"], "summary": "\nPOST `/api/v0/main-frontend/users/my-courses/:course_id/hide` - Hides a course from the\nauthenticated user's \"My courses\" list.", "operationId": "hideCourseFromMyCourses", "parameters": [ { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "Course hidden from the user's my-courses list" } } } }, "/api/v0/main-frontend/users/reset-password": { "post": { "tags": ["users"], "operationId": "resetUserPassword", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResetPasswordData" } } }, "required": true }, "responses": { "200": { "description": "Password reset status", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/users/reset-password-token-status": { "post": { "tags": ["users"], "operationId": "getResetPasswordTokenStatus", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ResetPasswordTokenPayload" } } }, "required": true }, "responses": { "200": { "description": "Reset password token validity", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/users/send-reset-password-email": { "post": { "tags": ["users"], "operationId": "sendResetPasswordEmail", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/EmailData" } } }, "required": true }, "responses": { "200": { "description": "Reset password email accepted", "content": { "text/plain": { "schema": { "type": "boolean" } } } } } } }, "/api/v0/main-frontend/users/user-research-consents": { "post": { "tags": ["users"], "summary": "\nPOST `/api/v0/main-frontend/users/user-research-consents` - Adds a research consent for a student.", "operationId": "createUserResearchConsent", "requestBody": { "content": { "application/json": { "schema": { "$ref": "#/components/schemas/ConsentData" } } }, "required": true }, "responses": { "200": { "description": "User research consent", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/UserResearchConsent" } } } } } } }, "/api/v0/main-frontend/users/user-research-form-question-answers": { "get": { "tags": ["users"], "summary": "\nGET `/api/v0/main-frontend/users/get-user-research-consents` - Gets all users research consents for a course specific research form.", "operationId": "getUserResearchFormQuestionAnswers", "responses": { "200": { "description": "Research form answers for user", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ResearchFormQuestionAnswer" } } } } } } } }, "/api/v0/main-frontend/users/{user_id}": { "get": { "tags": ["users"], "summary": "\nGET `/api/v0/main-frontend/users/:id`", "operationId": "getUser", "parameters": [ { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/User" } } } } } } }, "/api/v0/main-frontend/users/{user_id}/course-enrollments": { "get": { "tags": ["users"], "summary": "\nGET `/api/v0/main-frontend/users/:id/course-enrollments`", "operationId": "getUserCourseEnrollments", "parameters": [ { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User course enrollments", "content": { "application/json": { "schema": { "$ref": "#/components/schemas/CourseEnrollmentsInfo" } } } } } } }, "/api/v0/main-frontend/users/{user_id}/courses/{course_id}/submission-times": { "get": { "tags": ["users"], "summary": "\nGET `/api/v0/main-frontend/users/:id/courses/:course_id/submission-times` - A user's exercise\nsubmission times in a course, each tagged with its exercise and module. Teacher/admin (global) view.", "operationId": "getUserCourseSubmissionTimes", "parameters": [ { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } }, { "name": "course_id", "in": "path", "description": "Course id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User course submission times", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserCourseSubmissionTime" } } } } } } } }, "/api/v0/main-frontend/users/{user_id}/roles": { "get": { "tags": ["users"], "summary": "\nGET `/api/v0/main-frontend/users/:id/roles` - All roles held by a user, across scopes. Teacher/admin\n(global) view; used to label the account (e.g. staff/teacher) on the user-details page.", "operationId": "getUserRoles", "parameters": [ { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User roles across scopes", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/Role" } } } } } } } }, "/api/v0/main-frontend/users/{user_id}/suspected-cheaters": { "get": { "tags": ["users"], "summary": "\nGET `/api/v0/main-frontend/users/:id/suspected-cheaters` - Cross-course suspected-cheater records for\na user, each paired with the course's applicable duration threshold. Teacher/admin (global) view;\nread-only (confirm/dismiss happen on the per-course cheaters page).", "operationId": "getUserSuspectedCheaters", "parameters": [ { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User suspected-cheater records across courses", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/UserSuspectedCheaterInfo" } } } } } } } }, "/api/v0/main-frontend/users/{user_id}/user-reset-exercise-logs": { "get": { "tags": ["users"], "summary": "\nGET `/api/v0/main-frontend/users/:id/user-reset-exercise-logs` - Get all logs of reset exercises for a user", "operationId": "getUserResetExerciseLogs", "parameters": [ { "name": "user_id", "in": "path", "description": "User id", "required": true, "schema": { "type": "string", "format": "uuid" } } ], "responses": { "200": { "description": "User reset exercise logs", "content": { "application/json": { "schema": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseResetLog" } } } } } } } } }, "components": { "schemas": { "ActivityProgress": { "type": "string", "description": "\nIndicates what is the user's completion status for a exercise.\n\nAs close as possible to LTI's activity progress for compatibility: .", "enum": ["Initialized", "Started", "InProgress", "Submitted", "Completed"] }, "AddPlanMemberRequest": { "type": "object", "required": ["email"], "properties": { "email": { "type": "string", "format": "email" } } }, "AnalysisCourseType": { "type": "string", "enum": ["compulsory", "elective"] }, "AnalysisWorkspaceV1": { "type": "object", "description": "Analysis stage form: course metadata, needs, wishes, market, resources, contributors.", "required": [ "mode_synchronous", "mode_asynchronous", "open_period_i", "open_period_ii", "open_period_iii", "open_period_iv", "open_period_all", "wishes_content_format_text", "wishes_content_format_video", "wishes_content_format_podcast", "wishes_content_format_xr" ], "properties": { "contributors_editors": { "type": ["string", "null"] }, "contributors_instructional_designer": { "type": ["string", "null"] }, "contributors_subject_matter_experts": { "type": ["string", "null"] }, "contributors_support_staff": { "type": ["string", "null"] }, "course_title": { "type": ["string", "null"] }, "course_type": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/AnalysisCourseType" } ] }, "credits": { "type": ["number", "null"], "format": "double" }, "degree_programme": { "type": ["string", "null"] }, "language": { "type": ["string", "null"] }, "market_results": { "type": ["string", "null"] }, "mode_asynchronous": { "type": "boolean" }, "mode_synchronous": { "type": "boolean" }, "open_period_all": { "type": "boolean" }, "open_period_i": { "type": "boolean" }, "open_period_ii": { "type": "boolean" }, "open_period_iii": { "type": "boolean" }, "open_period_iv": { "type": "boolean" }, "resources_purchase_budget": { "type": ["string", "null"] }, "resources_university": { "type": ["string", "null"] }, "responsible_teachers": { "type": ["string", "null"] }, "students_demographic_data": { "type": ["string", "null"] }, "target_group": { "type": ["string", "null"] }, "wishes_assessment_text": { "type": ["string", "null"] }, "wishes_content_format_notes": { "type": ["string", "null"] }, "wishes_content_format_podcast": { "type": "boolean" }, "wishes_content_format_text": { "type": "boolean" }, "wishes_content_format_video": { "type": "boolean" }, "wishes_content_format_xr": { "type": "boolean" }, "wishes_other_suggestions": { "type": ["string", "null"] }, "wishes_topics": { "type": ["string", "null"] } } }, "AnswerRequiringAttentionWithTasks": { "type": "object", "required": [ "id", "user_id", "created_at", "updated_at", "grading_progress", "submission_id", "exercise_id", "tasks", "given_peer_reviews", "received_peer_or_self_reviews", "received_peer_review_flagging_reports" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "data_json": {}, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "exercise_id": { "type": "string", "format": "uuid" }, "given_peer_reviews": { "type": "array", "items": { "$ref": "#/components/schemas/PeerReviewWithQuestionsAndAnswers" } }, "grading_progress": { "$ref": "#/components/schemas/GradingProgress" }, "id": { "type": "string", "format": "uuid" }, "received_peer_or_self_reviews": { "type": "array", "items": { "$ref": "#/components/schemas/PeerReviewWithQuestionsAndAnswers" } }, "received_peer_review_flagging_reports": { "type": "array", "items": { "$ref": "#/components/schemas/FlaggedAnswer" } }, "score_given": { "type": ["number", "null"], "format": "float" }, "submission_id": { "type": "string", "format": "uuid" }, "tasks": { "type": "array", "items": { "$ref": "#/components/schemas/CourseMaterialExerciseTask" } }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "AnswersRequiringAttention": { "type": "object", "required": ["exercise_max_points", "data", "total_pages"], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/AnswerRequiringAttentionWithTasks" } }, "exercise_max_points": { "type": "integer", "format": "int32" }, "total_pages": { "type": "integer", "format": "int32", "minimum": 0 } } }, "AuthorizedClientInfo": { "type": "object", "required": ["client_id", "client_name", "scopes"], "properties": { "client_id": { "type": "string", "format": "uuid" }, "client_name": { "type": "string" }, "scopes": { "type": "array", "items": { "type": "string" } } } }, "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" } } }, "AverageMetric": { "type": "object", "description": "A generic result representing an average metric over a time period.\nThe average value (e.g. average time in seconds) may be absent if no data is available.", "properties": { "average": { "type": ["number", "null"], "format": "double", "description": "The average value. For example, the average time (in seconds) from course start to first submission." }, "period": { "type": ["string", "null"], "format": "date-time", "description": "The start of the time period (e.g., day, week, month) associated with this metric." } } }, "BlockProposal": { "oneOf": [ { "allOf": [ { "$ref": "#/components/schemas/EditedBlockStillExistsData" }, { "type": "object", "required": ["type"], "properties": { "type": { "type": "string", "enum": ["edited-block-still-exists"] } } } ] }, { "allOf": [ { "$ref": "#/components/schemas/EditedBlockNoLongerExistsData" }, { "type": "object", "required": ["type"], "properties": { "type": { "type": "string", "enum": ["edited-block-no-longer-exists"] } } } ] } ] }, "BlockProposalAction": { "oneOf": [ { "type": "object", "required": ["data", "tag"], "properties": { "data": { "type": "string" }, "tag": { "type": "string", "enum": ["Accept"] } } }, { "type": "object", "required": ["tag"], "properties": { "tag": { "type": "string", "enum": ["Reject"] } } } ] }, "BlockProposalInfo": { "type": "object", "required": ["id", "action"], "properties": { "action": { "$ref": "#/components/schemas/BlockProposalAction" }, "id": { "type": "string", "format": "uuid" } } }, "BulkUserDetailsRequest": { "type": "object", "required": ["user_ids", "course_id"], "properties": { "course_id": { "type": "string", "format": "uuid" }, "user_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } } } }, "CertificateAllRequirements": { "type": "object", "required": ["certificate_configuration_id", "course_module_ids"], "properties": { "certificate_configuration_id": { "type": "string", "format": "uuid" }, "course_module_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } } } }, "CertificateConfiguration": { "type": "object", "required": [ "id", "created_at", "updated_at", "certificate_owner_name_y_pos", "certificate_owner_name_x_pos", "certificate_owner_name_font_size", "certificate_owner_name_text_color", "certificate_owner_name_text_anchor", "certificate_validate_url_y_pos", "certificate_validate_url_x_pos", "certificate_validate_url_font_size", "certificate_validate_url_text_color", "certificate_validate_url_text_anchor", "certificate_date_y_pos", "certificate_date_x_pos", "certificate_date_font_size", "certificate_date_text_color", "certificate_date_text_anchor", "certificate_locale", "paper_size", "background_svg_path", "background_svg_file_upload_id", "render_certificate_grade" ], "properties": { "background_svg_file_upload_id": { "type": "string", "format": "uuid" }, "background_svg_path": { "type": "string" }, "certificate_date_font_size": { "type": "string" }, "certificate_date_text_anchor": { "$ref": "#/components/schemas/CertificateTextAnchor" }, "certificate_date_text_color": { "type": "string" }, "certificate_date_x_pos": { "type": "string" }, "certificate_date_y_pos": { "type": "string" }, "certificate_grade_font_size": { "type": ["string", "null"] }, "certificate_grade_text_anchor": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CertificateTextAnchor" } ] }, "certificate_grade_text_color": { "type": ["string", "null"] }, "certificate_grade_x_pos": { "type": ["string", "null"] }, "certificate_grade_y_pos": { "type": ["string", "null"] }, "certificate_locale": { "type": "string" }, "certificate_owner_name_font_size": { "type": "string" }, "certificate_owner_name_text_anchor": { "$ref": "#/components/schemas/CertificateTextAnchor" }, "certificate_owner_name_text_color": { "type": "string" }, "certificate_owner_name_x_pos": { "type": "string" }, "certificate_owner_name_y_pos": { "type": "string" }, "certificate_validate_url_font_size": { "type": "string" }, "certificate_validate_url_text_anchor": { "$ref": "#/components/schemas/CertificateTextAnchor" }, "certificate_validate_url_text_color": { "type": "string" }, "certificate_validate_url_x_pos": { "type": "string" }, "certificate_validate_url_y_pos": { "type": "string" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "overlay_svg_file_upload_id": { "type": ["string", "null"], "format": "uuid" }, "overlay_svg_path": { "type": ["string", "null"] }, "paper_size": { "$ref": "#/components/schemas/PaperSize" }, "render_certificate_grade": { "type": "boolean" }, "updated_at": { "type": "string", "format": "date-time" } } }, "CertificateConfigurationAndRequirements": { "type": "object", "required": ["certificate_configuration", "requirements"], "properties": { "certificate_configuration": { "$ref": "#/components/schemas/CertificateConfiguration" }, "requirements": { "$ref": "#/components/schemas/CertificateAllRequirements" } } }, "CertificateConfigurationUpdate": { "type": "object", "required": ["course_module_id", "clear_overlay_svg_file", "render_certificate_grade"], "properties": { "background_svg_file_name": { "type": ["string", "null"] }, "certificate_date_font_size": { "type": ["string", "null"] }, "certificate_date_text_anchor": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CertificateTextAnchor" } ] }, "certificate_date_text_color": { "type": ["string", "null"] }, "certificate_date_x_pos": { "type": ["string", "null"] }, "certificate_date_y_pos": { "type": ["string", "null"] }, "certificate_grade_font_size": { "type": ["string", "null"] }, "certificate_grade_text_anchor": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CertificateTextAnchor" } ] }, "certificate_grade_text_color": { "type": ["string", "null"] }, "certificate_grade_x_pos": { "type": ["string", "null"] }, "certificate_grade_y_pos": { "type": ["string", "null"] }, "certificate_locale": { "type": ["string", "null"] }, "certificate_owner_name_font_size": { "type": ["string", "null"] }, "certificate_owner_name_text_anchor": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CertificateTextAnchor" } ] }, "certificate_owner_name_text_color": { "type": ["string", "null"] }, "certificate_owner_name_x_pos": { "type": ["string", "null"] }, "certificate_owner_name_y_pos": { "type": ["string", "null"] }, "certificate_validate_url_font_size": { "type": ["string", "null"] }, "certificate_validate_url_text_anchor": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CertificateTextAnchor" } ] }, "certificate_validate_url_text_color": { "type": ["string", "null"] }, "certificate_validate_url_x_pos": { "type": ["string", "null"] }, "certificate_validate_url_y_pos": { "type": ["string", "null"] }, "clear_overlay_svg_file": { "type": "boolean" }, "course_instance_id": { "type": ["string", "null"], "format": "uuid" }, "course_module_id": { "type": "string", "format": "uuid" }, "overlay_svg_file_name": { "type": ["string", "null"] }, "paper_size": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PaperSize" } ] }, "render_certificate_grade": { "type": "boolean" } } }, "CertificateGenerationRequest": { "type": "object", "required": ["certificate_configuration_id", "name_on_certificate"], "properties": { "certificate_configuration_id": { "type": "string", "format": "uuid" }, "grade": { "type": ["string", "null"] }, "name_on_certificate": { "type": "string" } } }, "CertificateGridRow": { "type": "object", "required": ["user_id"], "properties": { "certificate_id": { "type": ["string", "null"], "format": "uuid" }, "date_issued": { "type": ["string", "null"], "format": "date-time" }, "name_on_certificate": { "type": ["string", "null"] }, "user_id": { "type": "string", "format": "uuid" }, "verification_id": { "type": ["string", "null"] } } }, "CertificateTextAnchor": { "type": "string", "description": "How text should be positioned relative to the given coordinates. See .", "enum": ["start", "middle", "end"] }, "CertificateUpdateRequest": { "type": "object", "required": ["date_issued"], "properties": { "date_issued": { "type": "string", "format": "date-time" }, "name_on_certificate": { "type": ["string", "null"] } } }, "ChangePasswordData": { "type": "object", "required": ["old_password", "new_password"], "properties": { "new_password": { "type": "string" }, "old_password": { "type": "string" } } }, "Chapter": { "type": "object", "required": [ "id", "created_at", "updated_at", "name", "course_id", "chapter_number", "course_module_id" ], "properties": { "chapter_image_url": { "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" } } }, "ChapterAvailability": { "type": "object", "required": [ "chapter_id", "chapter_number", "chapter_name", "exercises_available", "points_available" ], "properties": { "chapter_id": { "type": "string", "format": "uuid" }, "chapter_name": { "type": "string" }, "chapter_number": { "type": "integer", "format": "int32" }, "exercises_available": { "type": "integer", "format": "int64" }, "points_available": { "type": "integer", "format": "int64" } } }, "ChapterLockStatusActionPayload": { "type": "object", "required": ["status"], "properties": { "status": { "$ref": "#/components/schemas/ChapterLockingStatus" } } }, "ChapterLockingStatus": { "type": "string", "enum": ["unlocked", "completed_and_locked", "not_unlocked_yet"] }, "ChapterScore": { "allOf": [ { "$ref": "#/components/schemas/DatabaseChapter" }, { "type": "object", "required": ["score_given", "score_total"], "properties": { "score_given": { "type": "number", "format": "float" }, "score_total": { "type": "integer", "format": "int32" } } } ] }, "ChapterUpdate": { "type": "object", "required": ["name"], "properties": { "color": { "type": ["string", "null"] }, "course_module_id": { "type": ["string", "null"], "format": "uuid", "description": "CHANGE TO NON NULL WHEN FRONTEND MODULE EDITING IMPLEMENTED" }, "deadline": { "type": ["string", "null"], "format": "date-time" }, "front_page_id": { "type": ["string", "null"], "format": "uuid" }, "name": { "type": "string" }, "opens_at": { "type": ["string", "null"], "format": "date-time" } } }, "ChatbotConfiguration": { "type": "object", "required": [ "id", "created_at", "updated_at", "course_id", "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", "use_tools", "default_chatbot", "suggest_next_messages" ], "properties": { "chatbot_name": { "type": "string" }, "course_id": { "type": "string", "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" }, "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" }, "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" }, "use_tools": { "type": "boolean" }, "verbosity": { "$ref": "#/components/schemas/VerbosityLevel" }, "weekly_tokens_per_user": { "type": "integer", "format": "int32" } } }, "ChatbotConfigurationModel": { "type": "object", "required": [ "id", "created_at", "updated_at", "model", "model_type", "default_model", "context_size" ], "properties": { "context_size": { "type": "integer", "format": "int32" }, "created_at": { "type": "string", "format": "date-time" }, "default_model": { "type": "boolean" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "model": { "type": "string" }, "model_type": { "$ref": "#/components/schemas/ModelType" }, "updated_at": { "type": "string", "format": "date-time" } } }, "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": {} } }, "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": {} } }, "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" } } }, "CodeGiveawayCode": { "type": "object", "required": [ "id", "created_at", "updated_at", "code_giveaway_id", "added_by_user_id", "code" ], "properties": { "added_by_user_id": { "type": "string", "format": "uuid" }, "code": { "type": "string" }, "code_giveaway_id": { "type": "string", "format": "uuid" }, "code_given_to_user_id": { "type": ["string", "null"], "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" } } }, "CohortActivity": { "type": "object", "description": "Represents cohort activity metrics for both weekly and daily cohorts.\nFor daily cohorts, `offset` will be populated (and `activity_period` may be computed from it);\nfor weekly cohorts, `offset` will be `None` and `activity_period` indicates the week start.", "required": ["active_users"], "properties": { "active_users": { "type": "integer", "format": "int64", "description": "The number of active users in this cohort for the given period." }, "activity_period": { "type": ["string", "null"], "format": "date-time", "description": "The activity period (for example, the start of the week or the computed activity day)." }, "cohort_start": { "type": ["string", "null"], "format": "date-time", "description": "The start date of the cohort (either day or week)." }, "offset": { "type": ["integer", "null"], "format": "int32", "description": "The day offset from the cohort start (only applicable for daily cohorts)." } } }, "CompleteCourseMetadata": { "type": "object", "required": [ "course", "course_instances", "default_module", "course_prerequisites", "course_audiences", "course_organization" ], "properties": { "course": { "$ref": "#/components/schemas/Course" }, "course_audiences": { "type": "array", "items": { "$ref": "#/components/schemas/CourseAudience" } }, "course_instances": { "type": "array", "items": { "$ref": "#/components/schemas/CourseInstance" } }, "course_organization": { "$ref": "#/components/schemas/DatabaseOrganization" }, "course_prerequisites": { "type": "array", "items": { "$ref": "#/components/schemas/CoursePrerequisite" } }, "default_module": { "$ref": "#/components/schemas/CourseModule" } } }, "CompletionGridRow": { "type": "object", "required": ["user_id", "module_id", "registered", "needs_to_be_reviewed"], "properties": { "grade": { "type": ["integer", "null"], "format": "int32" }, "module": { "type": ["string", "null"] }, "module_id": { "type": "string", "format": "uuid" }, "needs_to_be_reviewed": { "type": "boolean" }, "passed": { "type": ["boolean", "null"] }, "registered": { "type": "boolean" }, "user_id": { "type": "string", "format": "uuid" } } }, "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"] } } } ] }, "CompletionRegistrationLink": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string" } } }, "ConsentData": { "type": "object", "required": ["consent"], "properties": { "consent": { "type": "boolean" } } }, "ConsentDenyQuery": { "type": "object", "required": ["client_id", "redirect_uri", "state"], "properties": { "client_id": { "type": "string" }, "redirect_uri": { "type": "string" }, "state": { "type": "string" } } }, "ConsentQuery": { "type": "object", "required": ["client_id", "redirect_uri", "response_type", "scope", "state", "nonce"], "properties": { "client_id": { "type": "string" }, "code_challenge": { "type": ["string", "null"] }, "code_challenge_method": { "type": ["string", "null"] }, "nonce": { "type": "string" }, "redirect_uri": { "type": "string" }, "response_type": { "type": "string" }, "scope": { "type": "string" }, "state": { "type": "string" } } }, "ConsentResponse": { "type": "object", "required": ["redirect_uri"], "properties": { "redirect_uri": { "type": "string" } } }, "CopyCourseMode": { "oneOf": [ { "type": "object", "description": "Create a completely separate copy with a new course language group", "required": ["mode"], "properties": { "mode": { "type": "string", "enum": ["duplicate"] } } }, { "type": "object", "description": "Create a new language version within the same language group as the source", "required": ["mode"], "properties": { "mode": { "type": "string", "enum": ["same_language_group"] } } }, { "type": "object", "description": "Create a new language version in a specified language group", "required": ["target_course_id", "mode"], "properties": { "mode": { "type": "string", "enum": ["existing_language_group"] }, "target_course_id": { "type": "string", "format": "uuid" } } }, { "type": "object", "description": "Create a new language version in a new language group", "required": ["mode"], "properties": { "mode": { "type": "string", "enum": ["new_language_group"] } } } ] }, "CopyCourseRequest": { "allOf": [ { "$ref": "#/components/schemas/NewCourse" }, { "type": "object", "required": ["mode"], "properties": { "mode": { "$ref": "#/components/schemas/CopyCourseMode" } } } ] }, "CountResult": { "type": "object", "description": "A generic result representing a count metric over a time period.\nWhen the time period is not applicable (for overall totals), `period` will be `None`.", "required": ["count"], "properties": { "count": { "type": "integer", "format": "int64", "description": "The count (for example, the number of users)." }, "period": { "type": ["string", "null"], "format": "date-time", "description": "The start of the time period (e.g., day, week, month) associated with this count.\nFor overall totals, this will be `None`." } } }, "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"] }, "CourseAudience": { "type": "object", "required": ["id", "created_at", "updated_at", "course_id", "audience"], "properties": { "audience": { "type": "string" }, "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" } } }, "CourseBreadcrumbInfo": { "type": "object", "required": [ "course_id", "course_name", "course_slug", "organization_slug", "organization_name" ], "properties": { "course_id": { "type": "string", "format": "uuid" }, "course_name": { "type": "string" }, "course_slug": { "type": "string" }, "organization_name": { "type": "string" }, "organization_slug": { "type": "string" } } }, "CourseCompletionStats": { "type": "object", "required": [ "course_id", "course_name", "total_completions", "unique_users", "registered_completions", "not_registered_completions", "users_with_some_registered_completions", "users_with_some_unregistered_completions", "registered_ects_credits", "not_registered_ects_credits" ], "properties": { "course_id": { "type": "string", "format": "uuid" }, "course_name": { "type": "string" }, "not_registered_completions": { "type": "integer", "format": "int64" }, "not_registered_ects_credits": { "type": "number", "format": "float" }, "registered_completion_percentage": { "type": ["number", "null"], "format": "double" }, "registered_completions": { "type": "integer", "format": "int64" }, "registered_ects_credits": { "type": "number", "format": "float" }, "total_completions": { "type": "integer", "format": "int64" }, "unique_users": { "type": "integer", "format": "int64" }, "users_with_some_registered_completions": { "type": "integer", "format": "int64" }, "users_with_some_unregistered_completions": { "type": "integer", "format": "int64" } } }, "CourseCount": { "type": "object", "required": ["count"], "properties": { "count": { "type": "integer", "format": "int32", "minimum": 0 } } }, "CourseDesignerCourseSize": { "type": "string", "enum": ["small", "medium", "large"] }, "CourseDesignerPlan": { "type": "object", "required": ["id", "created_at", "updated_at", "created_by_user_id", "status"], "properties": { "active_stage": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CourseDesignerStage" } ] }, "created_at": { "type": "string", "format": "date-time" }, "created_by_user_id": { "type": "string", "format": "uuid" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "last_weekly_stage_email_sent_at": { "type": ["string", "null"], "format": "date-time" }, "name": { "type": ["string", "null"] }, "status": { "$ref": "#/components/schemas/CourseDesignerPlanStatus" }, "updated_at": { "type": "string", "format": "date-time" } } }, "CourseDesignerPlanDetails": { "type": "object", "required": ["plan", "members", "stages"], "properties": { "members": { "type": "array", "items": { "$ref": "#/components/schemas/CourseDesignerPlanMember" } }, "plan": { "$ref": "#/components/schemas/CourseDesignerPlan" }, "stages": { "type": "array", "items": { "$ref": "#/components/schemas/CourseDesignerPlanStageWithTasks" } } } }, "CourseDesignerPlanMember": { "type": "object", "required": ["id", "created_at", "updated_at", "user_id"], "properties": { "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "CourseDesignerPlanStage": { "type": "object", "required": [ "id", "created_at", "updated_at", "stage", "status", "planned_starts_on", "planned_ends_on" ], "properties": { "actual_completed_at": { "type": ["string", "null"], "format": "date-time" }, "actual_started_at": { "type": ["string", "null"], "format": "date-time" }, "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "planned_ends_on": { "type": "string", "format": "date" }, "planned_starts_on": { "type": "string", "format": "date" }, "stage": { "$ref": "#/components/schemas/CourseDesignerStage" }, "status": { "$ref": "#/components/schemas/CourseDesignerPlanStageStatus" }, "updated_at": { "type": "string", "format": "date-time" }, "workspace_data": {} } }, "CourseDesignerPlanStageStatus": { "type": "string", "enum": ["NotStarted", "InProgress", "Completed"] }, "CourseDesignerPlanStageTask": { "type": "object", "required": [ "id", "created_at", "updated_at", "course_designer_plan_stage_id", "title", "order_number", "is_completed", "is_auto_generated" ], "properties": { "completed_at": { "type": ["string", "null"], "format": "date-time" }, "completed_by_user_id": { "type": ["string", "null"], "format": "uuid" }, "course_designer_plan_stage_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "created_by_user_id": { "type": ["string", "null"], "format": "uuid" }, "description": { "type": ["string", "null"] }, "id": { "type": "string", "format": "uuid" }, "is_auto_generated": { "type": "boolean" }, "is_completed": { "type": "boolean" }, "order_number": { "type": "integer", "format": "int32" }, "title": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "CourseDesignerPlanStageWithTasks": { "allOf": [ { "$ref": "#/components/schemas/CourseDesignerPlanStage" }, { "type": "object", "required": ["tasks"], "properties": { "tasks": { "type": "array", "items": { "$ref": "#/components/schemas/CourseDesignerPlanStageTask" } } } } ] }, "CourseDesignerPlanStatus": { "type": "string", "enum": ["Draft", "Scheduling", "InProgress", "Completed", "Archived"] }, "CourseDesignerPlanSummary": { "type": "object", "required": [ "id", "created_at", "updated_at", "created_by_user_id", "status", "member_count", "stage_count" ], "properties": { "active_stage": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/CourseDesignerStage" } ] }, "created_at": { "type": "string", "format": "date-time" }, "created_by_user_id": { "type": "string", "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "last_weekly_stage_email_sent_at": { "type": ["string", "null"], "format": "date-time" }, "member_count": { "type": "integer", "format": "int64" }, "name": { "type": ["string", "null"] }, "stage_count": { "type": "integer", "format": "int64" }, "status": { "$ref": "#/components/schemas/CourseDesignerPlanStatus" }, "updated_at": { "type": "string", "format": "date-time" } } }, "CourseDesignerScheduleStageInput": { "type": "object", "required": ["stage", "planned_starts_on", "planned_ends_on"], "properties": { "planned_ends_on": { "type": "string", "format": "date" }, "planned_starts_on": { "type": "string", "format": "date" }, "stage": { "$ref": "#/components/schemas/CourseDesignerStage" } } }, "CourseDesignerScheduleSuggestionRequest": { "type": "object", "required": ["course_size", "starts_on"], "properties": { "course_size": { "$ref": "#/components/schemas/CourseDesignerCourseSize" }, "starts_on": { "type": "string", "format": "date" } } }, "CourseDesignerScheduleSuggestionResponse": { "type": "object", "required": ["stages"], "properties": { "stages": { "type": "array", "items": { "$ref": "#/components/schemas/CourseDesignerScheduleStageInput" } } } }, "CourseDesignerStage": { "type": "string", "enum": ["Analysis", "Design", "Development", "Implementation", "Evaluation"] }, "CourseDesignerStageWorkspace": { "oneOf": [ { "type": "object", "required": ["payload", "schema"], "properties": { "payload": { "$ref": "#/components/schemas/AnalysisWorkspaceV1" }, "schema": { "type": "string", "enum": ["analysis_v1"] } } } ], "description": "Discriminant for forward-compatible workspace payloads stored in `workspace_data`." }, "CourseEnrollmentInfo": { "type": "object", "required": [ "course_id", "course", "course_instances", "course_modules", "course_module_completions", "course_module_completions_needing_review", "first_enrolled_at", "is_current" ], "properties": { "course": { "$ref": "#/components/schemas/Course" }, "course_id": { "type": "string", "format": "uuid" }, "course_instances": { "type": "array", "items": { "$ref": "#/components/schemas/CourseInstance" } }, "course_module_completions": { "type": "array", "items": { "$ref": "#/components/schemas/CourseModuleCompletion" } }, "course_module_completions_needing_review": { "type": "integer", "format": "int32" }, "course_modules": { "type": "array", "items": { "$ref": "#/components/schemas/CourseModuleInfo" }, "description": "All non-deleted modules of the course, ordered by `order_number`." }, "first_enrolled_at": { "type": "string", "format": "date-time" }, "is_current": { "type": "boolean" }, "user_course_settings": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/UserCourseSettings" } ] } } }, "CourseEnrollmentsInfo": { "type": "object", "required": ["course_enrollments"], "properties": { "course_enrollments": { "type": "array", "items": { "$ref": "#/components/schemas/CourseEnrollmentInfo" } } } }, "CourseExam": { "type": "object", "required": ["id", "course_id", "course_name", "name"], "properties": { "course_id": { "type": "string", "format": "uuid" }, "course_name": { "type": "string" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" } } }, "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" } } }, "CourseInstanceCompletionSummary": { "type": "object", "required": ["course_modules", "users_with_course_module_completions"], "properties": { "course_modules": { "type": "array", "items": { "$ref": "#/components/schemas/CourseModule" } }, "users_with_course_module_completions": { "type": "array", "items": { "$ref": "#/components/schemas/UserWithModuleCompletions" } } } }, "CourseInstanceForm": { "type": "object", "required": ["teacher_in_charge_name", "teacher_in_charge_email"], "properties": { "closing_time": { "type": ["string", "null"], "format": "date-time" }, "description": { "type": ["string", "null"] }, "name": { "type": ["string", "null"] }, "opening_time": { "type": ["string", "null"], "format": "date-time" }, "support_email": { "type": ["string", "null"] }, "teacher_in_charge_email": { "type": "string" }, "teacher_in_charge_name": { "type": "string" } } }, "CourseMaterialExerciseTask": { "type": "object", "description": "Information necessary for the frontend to render an exercise task", "required": [ "id", "exercise_service_slug", "exercise_slide_id", "assignment", "order_number" ], "properties": { "assignment": {}, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "exercise_iframe_url": { "type": ["string", "null"], "description": "\n If none, the task is not completable at the moment because the service needs to\n be configured to the system." }, "exercise_service_slug": { "type": "string" }, "exercise_slide_id": { "type": "string", "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "model_solution_spec": {}, "order_number": { "type": "integer", "format": "int32" }, "previous_submission": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ExerciseTaskSubmission" } ] }, "previous_submission_grading": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ExerciseTaskGrading" } ] }, "pseudonumous_user_id": { "type": ["string", "null"], "format": "uuid", "description": "\n Unique for each (exercise_service, user) combo. If none, the task is not completable at the moment because the service needs to\n be configured to the system." }, "public_spec": {} } }, "CourseMetadata": { "type": "object", "required": ["course_audiences", "course_prerequisites"], "properties": { "course_audiences": { "type": "array", "items": { "$ref": "#/components/schemas/CourseAudience" } }, "course_description": { "type": ["string", "null"] }, "course_prerequisites": { "type": "array", "items": { "$ref": "#/components/schemas/CoursePrerequisite" } } } }, "CourseMetadataUpdate": { "type": "object", "required": ["course_audiences", "course_prerequisites"], "properties": { "course_audiences": { "type": "array", "items": { "$ref": "#/components/schemas/NewCourseAudience" } }, "course_description": { "type": ["string", "null"] }, "course_prerequisites": { "type": "array", "items": { "$ref": "#/components/schemas/NewCoursePrerequisite" } } } }, "CourseModule": { "type": "object", "description": "\n * Based on [CourseModulesSchema] but completion_policy parsed and addded (and some not needeed fields removed).", "required": [ "id", "created_at", "updated_at", "course_id", "order_number", "completion_policy", "enable_registering_completion_to_uh_open_university", "certification_enabled" ], "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_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" } } }, "CourseModuleCompletion": { "type": "object", "required": [ "id", "created_at", "updated_at", "course_id", "course_module_id", "user_id", "completion_date", "completion_language", "eligible_for_ects", "email", "passed", "prerequisite_modules_completed", "needs_to_be_reviewed" ], "properties": { "completion_date": { "type": "string", "format": "date-time" }, "completion_granter_user_id": { "type": ["string", "null"], "format": "uuid" }, "completion_language": { "type": "string" }, "completion_registration_attempt_date": { "type": ["string", "null"], "format": "date-time" }, "course_id": { "type": "string", "format": "uuid" }, "course_module_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "eligible_for_ects": { "type": "boolean" }, "email": { "type": "string" }, "grade": { "type": ["integer", "null"], "format": "int32" }, "id": { "type": "string", "format": "uuid" }, "needs_to_be_reviewed": { "type": "boolean" }, "passed": { "type": "boolean" }, "prerequisite_modules_completed": { "type": "boolean" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "CourseModuleCompletionWithRegistrationInfo": { "type": "object", "required": [ "course_module_id", "created_at", "passed", "prerequisite_modules_completed", "registered", "needs_to_be_reviewed", "user_id", "completion_date" ], "properties": { "completion_date": { "type": "string", "format": "date-time" }, "completion_registration_attempt_date": { "type": ["string", "null"], "format": "date-time", "description": "When the student has attempted to register the completion." }, "course_module_id": { "type": "string", "format": "uuid", "description": "ID of the course module." }, "created_at": { "type": "string", "format": "date-time", "description": "When the record was created" }, "grade": { "type": ["integer", "null"], "format": "int32", "description": "Grade that the student received for the completion." }, "needs_to_be_reviewed": { "type": "boolean", "description": "Whether or not the completion needs to be reviewed by the teacher." }, "passed": { "type": "boolean", "description": "Whether or not the student is eligible for credit for the completion." }, "prerequisite_modules_completed": { "type": "boolean", "description": "Whether or not the student is qualified for credit based on other modules in the course." }, "registered": { "type": "boolean", "description": "Whether or not the completion has been registered to a study registry." }, "user_id": { "type": "string", "format": "uuid", "description": "ID of the user for the completion." } } }, "CourseModuleInfo": { "type": "object", "description": "Slim module descriptor so the frontend can label per-module completions and show \"X of Y modules\"\nwithout a separate course-structure fetch. Default (base) module has `name = None`.", "required": ["id", "order_number", "exercise_count", "daily_submissions"], "properties": { "daily_submissions": { "type": "array", "items": { "$ref": "#/components/schemas/DailySubmissionCount" }, "description": "This user's exercise submissions in this module bucketed by UTC day, ascending. Empty if none." }, "exercise_count": { "type": "integer", "format": "int32", "description": "Number of non-deleted exercises in this module. Submission density is divided by this so courses\nof very different size stay comparable. `0` if the module has no chapter-bound exercises." }, "first_submission_at": { "type": ["string", "null"], "format": "date-time", "description": "Earliest exercise submission by this user in this module. No module \"start\" is stored, so the\nfrontend uses this to infer when an additional module was first worked on. `None` if untouched." }, "id": { "type": "string", "format": "uuid" }, "name": { "type": ["string", "null"] }, "order_number": { "type": "integer", "format": "int32" } } }, "CourseModuleThresholdInfo": { "type": "object", "description": "Per-module threshold configuration plus the policy-derived limits the configuration UI needs to\nrender and validate the threshold form. Computed server-side so the exemption rule and the\nminimum/default values live in one place instead of being duplicated in the frontend.", "required": ["course_module_id", "minimum_duration_seconds", "default_duration_seconds"], "properties": { "configured_duration_seconds": { "type": ["integer", "null"], "format": "int32", "description": "The explicitly configured threshold in seconds, or `None` when the module has no threshold\nrow and [`Self::default_duration_seconds`] applies." }, "course_module_id": { "type": "string", "format": "uuid" }, "default_duration_seconds": { "type": "integer", "format": "int32", "description": "The threshold applied when none is configured." }, "minimum_duration_seconds": { "type": "integer", "format": "int32", "description": "The smallest threshold a teacher may save for this module: `0` for small (exempt) modules,\notherwise [`MINIMUM_CHEATER_THRESHOLD_SECONDS`]." } } }, "CoursePrerequisite": { "type": "object", "required": ["id", "created_at", "updated_at", "course_id", "prerequisite"], "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" }, "prerequisite": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "CourseStructure": { "type": "object", "required": ["course", "pages", "chapters", "modules"], "properties": { "chapters": { "type": "array", "items": { "$ref": "#/components/schemas/Chapter" } }, "course": { "$ref": "#/components/schemas/Course" }, "modules": { "type": "array", "items": { "$ref": "#/components/schemas/CourseModule" } }, "pages": { "type": "array", "items": { "$ref": "#/components/schemas/Page" } } } }, "CourseStudentListRow": { "type": "object", "description": "One row of the paginated student identity list (one row per distinct enrolled user).", "required": ["user_id", "course_instances", "has_active_instance"], "properties": { "course_instances": { "type": "array", "items": { "type": "string" }, "description": "Names of the non-deleted course instances the user is enrolled in for this course." }, "email": { "type": ["string", "null"] }, "first_name": { "type": ["string", "null"] }, "has_active_instance": { "type": "boolean", "description": "Whether the user has any enrollment into a non-deleted instance. Separates the unnamed default\ninstance (true) from a since-deleted instance (false) when `course_instances` is empty." }, "last_name": { "type": ["string", "null"] }, "user_id": { "type": "string", "format": "uuid" } } }, "CourseStudentsProgressStructure": { "type": "object", "description": "Course-level progress structure for the Progress tab. Does not depend on which students are on\nthe current page, so it is fetched once and cached per course (not per identity page).", "required": ["chapter_locking_enabled", "chapters", "chapter_availability"], "properties": { "chapter_availability": { "type": "array", "items": { "$ref": "#/components/schemas/ChapterAvailability" } }, "chapter_locking_enabled": { "type": "boolean" }, "chapters": { "type": "array", "items": { "$ref": "#/components/schemas/DatabaseChapter" } } } }, "CourseStudentsProgressUsers": { "type": "object", "description": "Per-user progress detail for the Progress tab, scoped to the requested `user_ids`.", "required": ["user_chapter_progress", "user_chapter_locking_statuses"], "properties": { "user_chapter_locking_statuses": { "type": "array", "items": { "$ref": "#/components/schemas/UserChapterLockingStatus" } }, "user_chapter_progress": { "type": "array", "items": { "$ref": "#/components/schemas/UserChapterProgress" } } } }, "CourseUpdate": { "type": "object", "required": [ "name", "is_draft", "is_test_mode", "can_add_chatbot", "is_unlisted", "is_joinable_by_code_only", "ask_marketing_consent", "flagged_answers_threshold", "flagged_answers_skip_manual_review_and_allow_retry", "chapter_locking_enabled", "ai_policy" ], "properties": { "ai_policy": { "$ref": "#/components/schemas/CourseAiPolicy" }, "ask_marketing_consent": { "type": "boolean" }, "can_add_chatbot": { "type": "boolean" }, "chapter_locking_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" }, "course_material_ai_instructions": { "type": ["boolean", "null"] }, "description": { "type": ["string", "null"] }, "flagged_answers_skip_manual_review_and_allow_retry": { "type": "boolean" }, "flagged_answers_threshold": { "type": "integer", "format": "int32" }, "is_draft": { "type": "boolean" }, "is_joinable_by_code_only": { "type": "boolean" }, "is_test_mode": { "type": "boolean" }, "is_unlisted": { "type": "boolean" }, "name": { "type": "string" } } }, "CreateCourseDesignerPlanRequest": { "type": "object", "properties": { "name": { "type": ["string", "null"] } } }, "CreateCourseDesignerStageTaskRequest": { "type": "object", "required": ["title"], "properties": { "description": { "type": ["string", "null"] }, "title": { "type": "string" } } }, "CronJobInfo": { "type": "object", "required": ["name", "schedule"], "properties": { "last_schedule_time": { "type": ["string", "null"] }, "name": { "type": "string" }, "schedule": { "type": "string" } } }, "DailySubmissionCount": { "type": "object", "description": "One UTC day's exercise-submission count for a module, used for the activity-density violins on the\ncross-course timeline. `day` is midnight of the day the submissions fall in.", "required": ["day", "count"], "properties": { "count": { "type": "integer", "format": "int32" }, "day": { "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" } } }, "DatabaseOrganization": { "type": "object", "required": ["id", "slug", "created_at", "updated_at", "name", "hidden"], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "description": { "type": ["string", "null"] }, "hidden": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "organization_image_path": { "type": ["string", "null"] }, "slug": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "DeploymentInfo": { "type": "object", "required": ["name", "replicas", "ready_replicas", "selector_labels"], "properties": { "name": { "type": "string" }, "ready_replicas": { "type": "integer", "format": "int32" }, "replicas": { "type": "integer", "format": "int32" }, "selector_labels": { "type": "object", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } } } }, "DomainCompletionStats": { "type": "object", "required": [ "email_domain", "total_completions", "unique_users", "registered_completions", "not_registered_completions", "users_with_some_registered_completions", "users_with_some_unregistered_completions", "registered_ects_credits", "not_registered_ects_credits" ], "properties": { "email_domain": { "type": "string" }, "not_registered_completions": { "type": "integer", "format": "int64" }, "not_registered_ects_credits": { "type": "number", "format": "float" }, "registered_completion_percentage": { "type": ["number", "null"], "format": "double" }, "registered_completions": { "type": "integer", "format": "int64" }, "registered_ects_credits": { "type": "number", "format": "float" }, "total_completions": { "type": "integer", "format": "int64" }, "unique_users": { "type": "integer", "format": "int64" }, "users_with_some_registered_completions": { "type": "integer", "format": "int64" }, "users_with_some_unregistered_completions": { "type": "integer", "format": "int64" } } }, "EditProposalInfo": { "type": "object", "required": ["page_id", "page_proposal_id", "block_proposals"], "properties": { "block_proposals": { "type": "array", "items": { "$ref": "#/components/schemas/BlockProposalInfo" } }, "page_id": { "type": "string", "format": "uuid" }, "page_proposal_id": { "type": "string", "format": "uuid" } } }, "EditedBlockNoLongerExistsData": { "type": "object", "required": ["id", "block_id", "changed_text", "original_text", "status"], "properties": { "block_id": { "type": "string", "format": "uuid" }, "changed_text": { "type": "string" }, "id": { "type": "string", "format": "uuid" }, "original_text": { "type": "string" }, "status": { "$ref": "#/components/schemas/ProposalStatus" } } }, "EditedBlockStillExistsData": { "type": "object", "required": ["id", "block_id", "current_text", "changed_text", "original_text", "status"], "properties": { "accept_preview": { "type": ["string", "null"] }, "block_id": { "type": "string", "format": "uuid" }, "changed_text": { "type": "string" }, "current_text": { "type": "string" }, "id": { "type": "string", "format": "uuid" }, "original_text": { "type": "string" }, "status": { "$ref": "#/components/schemas/ProposalStatus" } } }, "EmailData": { "type": "object", "required": ["email", "language"], "properties": { "email": { "type": "string" }, "language": { "type": "string" } } }, "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" } } }, "EmailTemplateNew": { "type": "object", "required": ["template_type"], "properties": { "content": {}, "language": { "type": ["string", "null"] }, "subject": { "type": ["string", "null"] }, "template_type": { "$ref": "#/components/schemas/EmailTemplateType" } } }, "EmailTemplateType": { "type": "string", "enum": ["reset_password_email", "delete_user_email", "confirm_email_code", "generic"] }, "EventInfo": { "type": "object", "required": ["name"], "properties": { "count": { "type": ["integer", "null"], "format": "int32" }, "first_timestamp": { "type": ["string", "null"] }, "involved_object_kind": { "type": ["string", "null"] }, "involved_object_name": { "type": ["string", "null"] }, "last_timestamp": { "type": ["string", "null"] }, "message": { "type": ["string", "null"] }, "name": { "type": "string" }, "reason": { "type": ["string", "null"] }, "type_": { "type": ["string", "null"] } } }, "Exam": { "type": "object", "required": [ "id", "name", "instructions", "page_id", "courses", "time_minutes", "minimum_points_treshold", "language", "grade_manually" ], "properties": { "courses": { "type": "array", "items": { "$ref": "#/components/schemas/Course" } }, "ends_at": { "type": ["string", "null"], "format": "date-time" }, "grade_manually": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "instructions": {}, "language": { "type": "string" }, "minimum_points_treshold": { "type": "integer", "format": "int32" }, "name": { "type": "string" }, "page_id": { "type": "string", "format": "uuid" }, "starts_at": { "type": ["string", "null"], "format": "date-time" }, "time_minutes": { "type": "integer", "format": "int32" } } }, "ExamCourseInfo": { "type": "object", "required": ["course_id"], "properties": { "course_id": { "type": "string", "format": "uuid" } } }, "ExamEnrollment": { "type": "object", "required": [ "user_id", "exam_id", "started_at", "is_teacher_testing", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "ended_at": { "type": ["string", "null"], "format": "date-time" }, "exam_id": { "type": "string", "format": "uuid" }, "is_teacher_testing": { "type": "boolean" }, "show_exercise_answers": { "type": ["boolean", "null"] }, "started_at": { "type": "string", "format": "date-time" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "Exercise": { "type": "object", "required": [ "id", "created_at", "updated_at", "name", "page_id", "score_maximum", "order_number", "limit_number_of_tries", "needs_peer_review", "needs_self_review", "use_course_default_peer_or_self_review_config", "teacher_reviews_answer_after_locking" ], "properties": { "chapter_id": { "type": ["string", "null"], "format": "uuid" }, "copied_from": { "type": ["string", "null"], "format": "uuid" }, "course_id": { "type": ["string", "null"], "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deadline": { "type": ["string", "null"], "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "exam_id": { "type": ["string", "null"], "format": "uuid" }, "exercise_language_group_id": { "type": ["string", "null"], "format": "uuid" }, "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" }, "page_id": { "type": "string", "format": "uuid" }, "score_maximum": { "type": "integer", "format": "int32" }, "teacher_reviews_answer_after_locking": { "type": "boolean" }, "updated_at": { "type": "string", "format": "date-time" }, "use_course_default_peer_or_self_review_config": { "type": "boolean" } } }, "ExerciseAnswersInCourseRequiringAttentionCount": { "type": "object", "required": ["id", "name", "page_id", "order_number"], "properties": { "chapter_id": { "type": ["string", "null"], "format": "uuid" }, "count": { "type": ["integer", "null"], "format": "int32" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "order_number": { "type": "integer", "format": "int32" }, "page_id": { "type": "string", "format": "uuid" } } }, "ExerciseCsvExportTaskOption": { "type": "object", "required": [ "exercise_task_id", "exercise_type", "order_number", "supports_csv_export_definitions", "supports_csv_export_answers" ], "properties": { "exercise_task_id": { "type": "string", "format": "uuid" }, "exercise_type": { "type": "string" }, "order_number": { "type": "integer", "format": "int32" }, "supports_csv_export_answers": { "type": "boolean" }, "supports_csv_export_definitions": { "type": "boolean" } } }, "ExerciseRepository": { "type": "object", "required": ["id", "url", "status"], "properties": { "course_id": { "type": ["string", "null"], "format": "uuid" }, "error_message": { "type": ["string", "null"] }, "exam_id": { "type": ["string", "null"], "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "status": { "$ref": "#/components/schemas/ExerciseRepositoryStatus" }, "url": { "type": "string" } } }, "ExerciseRepositoryStatus": { "type": "string", "enum": ["Pending", "Success", "Failure"] }, "ExerciseRepositoryUpdate": { "type": "object", "required": ["url"], "properties": { "url": { "type": "string" } } }, "ExerciseResetLog": { "type": "object", "required": [ "id", "reset_for", "exercise_id", "exercise_name", "course_id", "reset_at", "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" }, "exercise_id": { "type": "string", "format": "uuid" }, "exercise_name": { "type": "string" }, "id": { "type": "string", "format": "uuid" }, "reason": { "type": ["string", "null"] }, "reset_at": { "type": "string", "format": "date-time" }, "reset_by": { "type": ["string", "null"], "format": "uuid" }, "reset_by_first_name": { "type": ["string", "null"] }, "reset_by_last_name": { "type": ["string", "null"] }, "reset_for": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ExerciseService": { "type": "object", "required": [ "id", "created_at", "updated_at", "name", "slug", "public_url", "max_reprocessing_submissions_at_once" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "internal_url": { "type": ["string", "null"], "description": "This is needed because connecting to services directly inside the cluster with a special url is much for efficient than connecting to the same service with a url that would get routed though the internet. If not defined, use we can reach the service with the public url." }, "max_reprocessing_submissions_at_once": { "type": "integer", "format": "int32" }, "name": { "type": "string" }, "public_url": { "type": "string" }, "slug": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ExerciseServiceNewOrUpdate": { "type": "object", "required": ["name", "slug", "public_url", "max_reprocessing_submissions_at_once"], "properties": { "internal_url": { "type": ["string", "null"] }, "max_reprocessing_submissions_at_once": { "type": "integer", "format": "int32" }, "name": { "type": "string" }, "public_url": { "type": "string" }, "slug": { "type": "string" } } }, "ExerciseServiceWithError": { "type": "object", "required": ["exercise_service"], "properties": { "exercise_service": { "$ref": "#/components/schemas/ExerciseService" }, "service_info_error": { "type": ["string", "null"] } } }, "ExerciseSlideSubmission": { "type": "object", "required": [ "id", "created_at", "updated_at", "exercise_slide_id", "exercise_id", "user_id", "user_points_update_strategy" ], "properties": { "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" }, "exercise_id": { "type": "string", "format": "uuid" }, "exercise_slide_id": { "type": "string", "format": "uuid" }, "flag_count": { "type": ["integer", "null"], "format": "int32" }, "id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" }, "user_points_update_strategy": { "$ref": "#/components/schemas/UserPointsUpdateStrategy" } } }, "ExerciseSlideSubmissionAndUserExerciseState": { "type": "object", "required": [ "exercise", "exercise_slide_submission", "user_exercise_state", "user_exam_enrollment" ], "properties": { "exercise": { "$ref": "#/components/schemas/Exercise" }, "exercise_slide_submission": { "$ref": "#/components/schemas/ExerciseSlideSubmission" }, "teacher_grading_decision": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/TeacherGradingDecision" } ] }, "user_exam_enrollment": { "$ref": "#/components/schemas/ExamEnrollment" }, "user_exercise_state": { "$ref": "#/components/schemas/UserExerciseState" } } }, "ExerciseSlideSubmissionAndUserExerciseStateList": { "type": "object", "required": ["data", "total_pages"], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseSlideSubmissionAndUserExerciseState" } }, "total_pages": { "type": "integer", "format": "int32", "minimum": 0 } } }, "ExerciseSlideSubmissionCount": { "type": "object", "properties": { "count": { "type": ["integer", "null"], "format": "int32" }, "date": { "type": ["string", "null"], "format": "date" } } }, "ExerciseSlideSubmissionCountByExercise": { "type": "object", "required": ["exercise_id", "exercise_name"], "properties": { "count": { "type": ["integer", "null"], "format": "int32" }, "exercise_id": { "type": "string", "format": "uuid" }, "exercise_name": { "type": "string" } } }, "ExerciseSlideSubmissionCountByWeekAndHour": { "type": "object", "properties": { "count": { "type": ["integer", "null"], "format": "int32" }, "hour": { "type": ["integer", "null"], "format": "int32" }, "isodow": { "type": ["integer", "null"], "format": "int32" } } }, "ExerciseSlideSubmissionInfo": { "type": "object", "required": ["tasks", "exercise", "exercise_slide_submission"], "properties": { "exercise": { "$ref": "#/components/schemas/Exercise" }, "exercise_slide_submission": { "$ref": "#/components/schemas/ExerciseSlideSubmission" }, "tasks": { "type": "array", "items": { "$ref": "#/components/schemas/CourseMaterialExerciseTask" } }, "user_exercise_state": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/UserExerciseState" } ] } } }, "ExerciseStatusSummaryForUser": { "type": "object", "required": [ "exercise", "exercise_slide_submissions", "given_peer_or_self_review_submissions", "given_peer_or_self_review_question_submissions", "received_peer_or_self_review_submissions", "received_peer_or_self_review_question_submissions", "peer_or_self_review_questions" ], "properties": { "exercise": { "$ref": "#/components/schemas/Exercise" }, "exercise_slide_submissions": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseSlideSubmission" } }, "given_peer_or_self_review_question_submissions": { "type": "array", "items": { "$ref": "#/components/schemas/PeerOrSelfReviewQuestionSubmission" } }, "given_peer_or_self_review_submissions": { "type": "array", "items": { "$ref": "#/components/schemas/PeerOrSelfReviewSubmissionWithSubmissionOwner" } }, "peer_or_self_review_questions": { "type": "array", "items": { "$ref": "#/components/schemas/PeerOrSelfReviewQuestion" } }, "peer_review_queue_entry": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/PeerReviewQueueEntry" } ] }, "received_peer_or_self_review_question_submissions": { "type": "array", "items": { "$ref": "#/components/schemas/PeerOrSelfReviewQuestionSubmission" } }, "received_peer_or_self_review_submissions": { "type": "array", "items": { "$ref": "#/components/schemas/PeerOrSelfReviewSubmissionWithSubmissionOwner" } }, "teacher_grading_decision": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/TeacherGradingDecision" } ] }, "user_exercise_state": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/UserExerciseState" } ] } } }, "ExerciseSubmissions": { "type": "object", "required": ["data", "total_pages"], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/ExerciseSlideSubmission" } }, "total_pages": { "type": "integer", "format": "int32", "minimum": 0 } } }, "ExerciseTaskGrading": { "type": "object", "required": [ "id", "created_at", "updated_at", "exercise_task_submission_id", "exercise_id", "exercise_task_id", "grading_priority", "grading_progress" ], "properties": { "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" }, "exercise_id": { "type": "string", "format": "uuid" }, "exercise_task_id": { "type": "string", "format": "uuid" }, "exercise_task_submission_id": { "type": "string", "format": "uuid" }, "feedback_json": {}, "feedback_text": { "type": ["string", "null"] }, "grading_completed_at": { "type": ["string", "null"], "format": "date-time" }, "grading_priority": { "type": "integer", "format": "int32" }, "grading_progress": { "$ref": "#/components/schemas/GradingProgress" }, "grading_started_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "score_given": { "type": ["number", "null"], "format": "float" }, "unscaled_score_given": { "type": ["number", "null"], "format": "float" }, "unscaled_score_maximum": { "type": ["integer", "null"], "format": "int32" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ExerciseTaskGradingResult": { "type": "object", "required": ["grading_progress", "score_given", "score_maximum"], "properties": { "feedback_json": {}, "feedback_text": { "type": ["string", "null"] }, "grading_progress": { "$ref": "#/components/schemas/GradingProgress" }, "score_given": { "type": "number", "format": "float" }, "score_maximum": { "type": "integer", "format": "int32" }, "set_user_variables": { "type": ["object", "null"], "additionalProperties": {}, "propertyNames": { "type": "string" } } } }, "ExerciseTaskSubmission": { "type": "object", "required": [ "id", "created_at", "updated_at", "exercise_slide_submission_id", "exercise_task_id", "exercise_slide_id" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "data_json": {}, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "exercise_slide_id": { "type": "string", "format": "uuid" }, "exercise_slide_submission_id": { "type": "string", "format": "uuid" }, "exercise_task_grading_id": { "type": ["string", "null"], "format": "uuid" }, "exercise_task_id": { "type": "string", "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "metadata": {}, "updated_at": { "type": "string", "format": "date-time" } } }, "ExerciseUserCounts": { "type": "object", "required": [ "exercise_name", "exercise_order_number", "page_order_number", "chapter_number", "exercise_id" ], "properties": { "chapter_number": { "type": "integer", "format": "int32" }, "exercise_id": { "type": "string", "format": "uuid" }, "exercise_name": { "type": "string" }, "exercise_order_number": { "type": "integer", "format": "int32" }, "n_users_attempted": { "type": ["integer", "null"], "format": "int64" }, "n_users_with_max_points": { "type": ["integer", "null"], "format": "int64" }, "n_users_with_some_points": { "type": ["integer", "null"], "format": "int64" }, "page_order_number": { "type": "integer", "format": "int32" } } }, "ExtendStageRequest": { "type": "object", "required": ["months"], "properties": { "months": { "type": "integer", "format": "int32", "minimum": 0 } } }, "Feedback": { "type": "object", "required": [ "id", "course_id", "feedback_given", "marked_as_read", "created_at", "blocks", "page_title", "page_url_path" ], "properties": { "blocks": { "type": "array", "items": { "$ref": "#/components/schemas/FeedbackBlock" } }, "course_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "feedback_given": { "type": "string" }, "id": { "type": "string", "format": "uuid" }, "marked_as_read": { "type": "boolean" }, "page_id": { "type": ["string", "null"], "format": "uuid" }, "page_title": { "type": "string" }, "page_url_path": { "type": "string" }, "selected_text": { "type": ["string", "null"] }, "user_id": { "type": ["string", "null"], "format": "uuid" } } }, "FeedbackBlock": { "type": "object", "required": ["id"], "properties": { "id": { "type": "string", "format": "uuid" }, "order_number": { "type": ["integer", "null"], "format": "int32" }, "text": { "type": ["string", "null"] } } }, "FeedbackCount": { "type": "object", "required": ["read", "unread"], "properties": { "read": { "type": "integer", "format": "int32", "minimum": 0 }, "unread": { "type": "integer", "format": "int32", "minimum": 0 } } }, "FlaggedAnswer": { "type": "object", "required": [ "id", "submission_id", "flagged_user", "flagged_by", "reason", "created_at", "updated_at" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "description": { "type": ["string", "null"] }, "flagged_by": { "type": "string", "format": "uuid" }, "flagged_user": { "type": "string", "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "reason": { "$ref": "#/components/schemas/ReportReason" }, "submission_id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" } } }, "GeneratedCertificate": { "type": "object", "required": [ "id", "created_at", "updated_at", "user_id", "name_on_certificate", "verification_id", "certificate_configuration_id" ], "properties": { "certificate_configuration_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" }, "name_on_certificate": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" }, "verification_id": { "type": "string" } } }, "GlobalCourseModuleStatEntry": { "type": "object", "required": [ "course_name", "course_id", "course_module_id", "organization_id", "organization_name", "year", "value" ], "properties": { "course_id": { "type": "string", "format": "uuid" }, "course_module_ects_credits": { "type": ["number", "null"], "format": "float" }, "course_module_id": { "type": "string", "format": "uuid" }, "course_module_name": { "type": ["string", "null"] }, "course_name": { "type": "string" }, "organization_id": { "type": "string", "format": "uuid" }, "organization_name": { "type": "string" }, "value": { "type": "integer", "format": "int64" }, "year": { "type": "string" } } }, "GlobalStatEntry": { "type": "object", "required": [ "course_name", "course_id", "organization_id", "organization_name", "year", "value" ], "properties": { "course_id": { "type": "string", "format": "uuid" }, "course_name": { "type": "string" }, "month": { "type": ["integer", "null"], "format": "int32" }, "organization_id": { "type": "string", "format": "uuid" }, "organization_name": { "type": "string" }, "value": { "type": "integer", "format": "int64" }, "year": { "type": "integer", "format": "int32" } } }, "GradingProgress": { "type": "string", "description": "\n\nTells what's the status of the grading progress for a user and exercise.\n\nAs close as possible LTI's grading progress for compatibility: ", "enum": ["Failed", "NotReady", "PendingManual", "Pending", "FullyGraded"] }, "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" } } }, "HealthStatus": { "type": "string", "enum": ["healthy", "warning", "error"] }, "HistoryChangeReason": { "type": "string", "enum": ["PageSaved", "HistoryRestored", "PageDeleted"] }, "HistoryRestoreData": { "type": "object", "required": ["history_id"], "properties": { "history_id": { "type": "string", "format": "uuid" } } }, "IngressInfo": { "type": "object", "required": ["name", "hosts", "paths"], "properties": { "class_name": { "type": ["string", "null"] }, "hosts": { "type": "array", "items": { "type": "string" } }, "name": { "type": "string" }, "paths": { "type": "array", "items": { "type": "string" } } } }, "JobInfo": { "type": "object", "required": ["name"], "properties": { "active": { "type": ["integer", "null"], "format": "int32" }, "failed": { "type": ["integer", "null"], "format": "int32" }, "name": { "type": "string" }, "succeeded": { "type": ["integer", "null"], "format": "int32" } } }, "JoinCourseWithJoinCodePayload": { "type": "object", "required": ["join_code"], "properties": { "join_code": { "type": "string" } } }, "ManualCompletionPreview": { "type": "object", "required": [ "already_completed_users", "first_time_completing_users", "non_enrolled_users" ], "properties": { "already_completed_users": { "type": "array", "items": { "$ref": "#/components/schemas/ManualCompletionPreviewUser" } }, "first_time_completing_users": { "type": "array", "items": { "$ref": "#/components/schemas/ManualCompletionPreviewUser" } }, "non_enrolled_users": { "type": "array", "items": { "$ref": "#/components/schemas/ManualCompletionPreviewUser" } } } }, "ManualCompletionPreviewUser": { "type": "object", "required": ["user_id", "passed"], "properties": { "first_name": { "type": ["string", "null"] }, "grade": { "type": ["integer", "null"], "format": "int32" }, "last_name": { "type": ["string", "null"] }, "passed": { "type": "boolean" }, "previous_best_grade": { "type": ["integer", "null"], "format": "int32" }, "user_id": { "type": "string", "format": "uuid" } } }, "MarkAsRead": { "type": "object", "required": ["read"], "properties": { "read": { "type": "boolean" } } }, "MaterialReference": { "type": "object", "required": ["id", "course_id", "citation_key", "reference", "created_at", "updated_at"], "properties": { "citation_key": { "type": "string" }, "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" }, "reference": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "ModelType": { "type": "string", "enum": ["GPTThinking", "GPTNonThinking", "GPTHardThinking", "Mistral"] }, "ModifiedModule": { "type": "object", "required": [ "id", "order_number", "completion_policy", "enable_registering_completion_to_uh_open_university" ], "properties": { "completion_policy": { "$ref": "#/components/schemas/CompletionPolicy" }, "completion_registration_link_override": { "type": ["string", "null"] }, "ects_credits": { "type": ["number", "null"], "format": "float" }, "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"] } } }, "Module": { "type": "object", "required": ["course_code", "description", "prerequisites"], "properties": { "course_code": { "type": "string" }, "description": { "type": "string" }, "prerequisites": { "type": "array", "items": { "type": "string" } } } }, "ModuleUpdates": { "type": "object", "required": ["new_modules", "deleted_modules", "modified_modules", "moved_chapters"], "properties": { "deleted_modules": { "type": "array", "items": { "type": "string", "format": "uuid" } }, "modified_modules": { "type": "array", "items": { "$ref": "#/components/schemas/ModifiedModule" } }, "moved_chapters": { "type": "array", "items": { "type": "array", "items": false, "prefixItems": [ { "type": "string", "format": "uuid" }, { "type": "string", "format": "uuid" } ] } }, "new_modules": { "type": "array", "items": { "$ref": "#/components/schemas/NewModule" } } } }, "MyCourse": { "allOf": [ { "$ref": "#/components/schemas/Course" }, { "type": "object", "required": ["can_hide"], "properties": { "can_hide": { "type": "boolean", "description": "Whether the course can be hidden from the \"My courses\" list. Only courses the user has\nenrolled in (and thus have user course settings) can be hidden." } } } ] }, "NewChapter": { "type": "object", "required": ["name", "course_id", "chapter_number"], "properties": { "chapter_number": { "type": "integer", "format": "int32" }, "color": { "type": ["string", "null"] }, "course_id": { "type": "string", "format": "uuid" }, "course_module_id": { "type": ["string", "null"], "format": "uuid", "description": "If undefined when creating a chapter, will use the course default one.\nCHANGE TO NON NULL WHEN FRONTEND MODULE EDITING IMPLEMENTED" }, "deadline": { "type": ["string", "null"], "format": "date-time" }, "front_page_id": { "type": ["string", "null"], "format": "uuid" }, "name": { "type": "string" }, "opens_at": { "type": ["string", "null"], "format": "date-time" } } }, "NewChatbotConf": { "type": "object", "required": [ "course_id", "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", "use_tools", "default_chatbot", "suggest_next_messages" ], "properties": { "chatbot_name": { "type": "string" }, "chatbotconf_id": { "type": ["string", "null"], "format": "uuid" }, "course_id": { "type": "string", "format": "uuid" }, "daily_tokens_per_user": { "type": "integer", "format": "int32" }, "default_chatbot": { "type": "boolean" }, "enabled_to_students": { "type": "boolean" }, "frequency_penalty": { "type": "number", "format": "float" }, "hide_citations": { "type": "boolean" }, "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" }, "reasoning_effort": { "$ref": "#/components/schemas/ReasoningEffortLevel" }, "suggest_next_messages": { "type": "boolean" }, "temperature": { "type": "number", "format": "float" }, "top_p": { "type": "number", "format": "float" }, "use_azure_search": { "type": "boolean" }, "use_semantic_reranking": { "type": "boolean" }, "use_tools": { "type": "boolean" }, "verbosity": { "$ref": "#/components/schemas/VerbosityLevel" }, "weekly_tokens_per_user": { "type": "integer", "format": "int32" } } }, "NewCodeGiveaway": { "type": "object", "required": ["course_id", "name"], "properties": { "course_id": { "type": "string", "format": "uuid" }, "course_module_id": { "type": ["string", "null"], "format": "uuid" }, "name": { "type": "string" }, "require_course_specific_consent_form_question_id": { "type": ["string", "null"], "format": "uuid" } } }, "NewCourse": { "type": "object", "description": "Represents the subset of page fields that are required to create a new course.", "required": [ "name", "slug", "organization_id", "language_code", "teacher_in_charge_name", "teacher_in_charge_email", "description", "is_draft", "is_test_mode", "is_unlisted", "copy_user_permissions", "is_joinable_by_code_only", "ask_marketing_consent", "can_add_chatbot" ], "properties": { "ask_marketing_consent": { "type": "boolean" }, "can_add_chatbot": { "type": "boolean" }, "copy_user_permissions": { "type": "boolean", "description": "If true, copies all user permissions from the original course to the new one." }, "description": { "type": "string" }, "flagged_answers_threshold": { "type": ["integer", "null"], "format": "int32" }, "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" }, "teacher_in_charge_email": { "type": "string", "description": "Email of the teacher who is responsible for the course. Must be a valid email." }, "teacher_in_charge_name": { "type": "string", "description": "Name of the teacher who is responsible for the course. Must be a valid name." } } }, "NewCourseAudience": { "type": "object", "required": ["audience"], "properties": { "audience": { "type": "string" } } }, "NewCoursePrerequisite": { "type": "object", "required": ["prerequisite"], "properties": { "prerequisite": { "type": "string" } } }, "NewExam": { "type": "object", "required": [ "name", "time_minutes", "organization_id", "minimum_points_treshold", "grade_manually" ], "properties": { "ends_at": { "type": ["string", "null"], "format": "date-time" }, "grade_manually": { "type": "boolean" }, "minimum_points_treshold": { "type": "integer", "format": "int32" }, "name": { "type": "string" }, "organization_id": { "type": "string", "format": "uuid" }, "starts_at": { "type": ["string", "null"], "format": "date-time" }, "time_minutes": { "type": "integer", "format": "int32" } } }, "NewExerciseRepository": { "type": "object", "required": ["git_url"], "properties": { "course_id": { "type": ["string", "null"], "format": "uuid" }, "deploy_key": { "type": ["string", "null"] }, "exam_id": { "type": ["string", "null"], "format": "uuid" }, "git_url": { "type": "string" }, "public_key": { "type": ["string", "null"] } } }, "NewMaterialReference": { "type": "object", "required": ["citation_key", "reference"], "properties": { "citation_key": { "type": "string" }, "reference": { "type": "string" } } }, "NewModule": { "type": "object", "required": [ "name", "order_number", "chapters", "completion_policy", "enable_registering_completion_to_uh_open_university" ], "properties": { "chapters": { "type": "array", "items": { "type": "string", "format": "uuid" } }, "completion_policy": { "$ref": "#/components/schemas/CompletionPolicy" }, "completion_registration_link_override": { "type": ["string", "null"] }, "ects_credits": { "type": ["number", "null"], "format": "float" }, "enable_registering_completion_to_uh_open_university": { "type": "boolean" }, "name": { "type": "string" }, "order_number": { "type": "integer", "format": "int32" }, "uh_course_code": { "type": ["string", "null"] } } }, "NewPage": { "type": "object", "description": "Represents the subset of page fields that are required to create a new page.", "required": [ "exercises", "exercise_slides", "exercise_tasks", "content", "url_path", "title", "hidden" ], "properties": { "chapter_id": { "type": ["string", "null"], "format": "uuid" }, "content": { "type": "array", "items": { "$ref": "#/components/schemas/GutenbergBlock" } }, "content_search_language": { "type": ["string", "null"], "description": "Read from the course's settings if None. If course_id is None as well, defaults to \"simple\"" }, "course_id": { "type": ["string", "null"], "format": "uuid" }, "exam_id": { "type": ["string", "null"], "format": "uuid" }, "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" } }, "front_page_of_chapter_id": { "type": ["string", "null"], "format": "uuid", "description": "If set, set this page to be the front page of this course part." }, "hidden": { "type": "boolean" }, "title": { "type": "string" }, "url_path": { "type": "string" } } }, "NewRegrading": { "type": "object", "required": ["user_points_update_strategy", "ids", "id_type"], "properties": { "id_type": { "$ref": "#/components/schemas/NewRegradingIdType" }, "ids": { "type": "array", "items": { "type": "string", "format": "uuid" } }, "user_points_update_strategy": { "$ref": "#/components/schemas/UserPointsUpdateStrategy" } } }, "NewRegradingIdType": { "type": "string", "enum": ["ExerciseTaskSubmissionId", "ExerciseId"] }, "NewTeacherGradingDecision": { "type": "object", "required": ["user_exercise_state_id", "exercise_id", "action", "hidden"], "properties": { "action": { "$ref": "#/components/schemas/TeacherDecisionType" }, "exercise_id": { "type": "string", "format": "uuid" }, "hidden": { "type": "boolean" }, "justification": { "type": ["string", "null"] }, "manual_points": { "type": ["number", "null"], "format": "float" }, "user_exercise_state_id": { "type": "string", "format": "uuid" } } }, "OrgExam": { "type": "object", "required": [ "id", "created_at", "updated_at", "name", "instructions", "time_minutes", "organization_id", "minimum_points_treshold", "grade_manually" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "ends_at": { "type": ["string", "null"], "format": "date-time" }, "grade_manually": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "instructions": {}, "language": { "type": ["string", "null"] }, "minimum_points_treshold": { "type": "integer", "format": "int32" }, "name": { "type": "string" }, "organization_id": { "type": "string", "format": "uuid" }, "starts_at": { "type": ["string", "null"], "format": "date-time" }, "time_minutes": { "type": "integer", "format": "int32" }, "updated_at": { "type": "string", "format": "date-time" } } }, "Organization": { "type": "object", "required": ["id", "slug", "created_at", "updated_at", "name", "hidden"], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "description": { "type": ["string", "null"] }, "hidden": { "type": "boolean" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "organization_image_url": { "type": ["string", "null"] }, "slug": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "OrganizationCreatePayload": { "type": "object", "required": ["name", "slug", "hidden"], "properties": { "hidden": { "type": "boolean" }, "name": { "type": "string" }, "slug": { "type": "string" } } }, "OrganizationUpdatePayload": { "type": "object", "required": ["name", "hidden", "slug"], "properties": { "hidden": { "type": "boolean" }, "name": { "type": "string" }, "slug": { "type": "string" } } }, "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" } } }, "PageAudioFile": { "type": "object", "required": ["id", "page_id", "created_at", "path", "mime_type"], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "mime_type": { "type": "string" }, "page_id": { "type": "string", "format": "uuid" }, "path": { "type": "string" } } }, "PageDetailsUpdate": { "type": "object", "description": "Represents the subset of page fields that can be updated from the main frontend dialog \"Edit page details\".", "required": ["title", "url_path"], "properties": { "title": { "type": "string" }, "url_path": { "type": "string" } } }, "PageHistory": { "type": "object", "required": [ "id", "created_at", "updated_at", "title", "content", "history_change_reason", "author_user_id", "page_id" ], "properties": { "author_user_id": { "type": "string", "format": "uuid" }, "content": {}, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "history_change_reason": { "$ref": "#/components/schemas/HistoryChangeReason" }, "id": { "type": "string", "format": "uuid" }, "page_id": { "type": "string", "format": "uuid" }, "restored_from_id": { "type": ["string", "null"], "format": "uuid" }, "title": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "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" } } }, "PageProposal": { "type": "object", "required": [ "id", "page_id", "pending", "created_at", "block_proposals", "page_title", "page_url_path" ], "properties": { "block_proposals": { "type": "array", "items": { "$ref": "#/components/schemas/BlockProposal" } }, "created_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "page_id": { "type": "string", "format": "uuid" }, "page_title": { "type": "string" }, "page_url_path": { "type": "string" }, "pending": { "type": "boolean" }, "user_id": { "type": ["string", "null"], "format": "uuid" } } }, "PageVisitDatumSummaryByCourse": { "type": "object", "required": ["id", "created_at", "updated_at", "num_visitors", "visit_date"], "properties": { "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" }, "id": { "type": "string", "format": "uuid" }, "num_visitors": { "type": "integer", "format": "int32" }, "referrer": { "type": ["string", "null"] }, "updated_at": { "type": "string", "format": "date-time" }, "utm_campaign": { "type": ["string", "null"] }, "utm_content": { "type": ["string", "null"] }, "utm_medium": { "type": ["string", "null"] }, "utm_source": { "type": ["string", "null"] }, "utm_term": { "type": ["string", "null"] }, "visit_date": { "type": "string", "format": "date" } } }, "PageVisitDatumSummaryByCourseDeviceTypes": { "type": "object", "required": ["id", "created_at", "updated_at", "num_visitors", "visit_date"], "properties": { "browser": { "type": ["string", "null"] }, "browser_version": { "type": ["string", "null"] }, "course_id": { "type": ["string", "null"], "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "device_type": { "type": ["string", "null"] }, "exam_id": { "type": ["string", "null"], "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "num_visitors": { "type": "integer", "format": "int32" }, "operating_system": { "type": ["string", "null"] }, "updated_at": { "type": "string", "format": "date-time" }, "visit_date": { "type": "string", "format": "date" } } }, "PageVisitDatumSummaryByCoursesCountries": { "type": "object", "required": ["id", "created_at", "updated_at", "num_visitors", "visit_date"], "properties": { "country": { "type": ["string", "null"] }, "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" }, "id": { "type": "string", "format": "uuid" }, "num_visitors": { "type": "integer", "format": "int32" }, "updated_at": { "type": "string", "format": "date-time" }, "visit_date": { "type": "string", "format": "date" } } }, "PageVisitDatumSummaryByPages": { "type": "object", "required": ["id", "created_at", "updated_at", "page_id", "num_visitors", "visit_date"], "properties": { "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" }, "id": { "type": "string", "format": "uuid" }, "num_visitors": { "type": "integer", "format": "int32" }, "page_id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" }, "visit_date": { "type": "string", "format": "date" } } }, "PaperSize": { "type": "string", "enum": ["horizontal-a4", "vertical-a4"] }, "PeerOrSelfReviewAnswer": { "oneOf": [ { "type": "object", "required": ["type"], "properties": { "type": { "type": "string", "enum": ["no-answer"] } } }, { "type": "object", "required": ["value", "type"], "properties": { "type": { "type": "string", "enum": ["essay"] }, "value": { "type": "string" } } }, { "type": "object", "required": ["value", "type"], "properties": { "type": { "type": "string", "enum": ["scale"] }, "value": { "type": "number", "format": "float" } } } ] }, "PeerOrSelfReviewQuestion": { "type": "object", "required": [ "id", "created_at", "updated_at", "peer_or_self_review_config_id", "order_number", "question", "question_type", "answer_required", "weight" ], "properties": { "answer_required": { "type": "boolean" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "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" }, "updated_at": { "type": "string", "format": "date-time" }, "weight": { "type": "number", "format": "float" } } }, "PeerOrSelfReviewQuestionAndAnswer": { "type": "object", "required": [ "peer_or_self_review_config_id", "peer_or_self_review_question_id", "peer_or_self_review_submission_id", "peer_review_question_submission_id", "order_number", "question", "answer", "answer_required" ], "properties": { "answer": { "$ref": "#/components/schemas/PeerOrSelfReviewAnswer" }, "answer_required": { "type": "boolean" }, "order_number": { "type": "integer", "format": "int32" }, "peer_or_self_review_config_id": { "type": "string", "format": "uuid" }, "peer_or_self_review_question_id": { "type": "string", "format": "uuid" }, "peer_or_self_review_submission_id": { "type": "string", "format": "uuid" }, "peer_review_question_submission_id": { "type": "string", "format": "uuid" }, "question": { "type": "string" } } }, "PeerOrSelfReviewQuestionSubmission": { "type": "object", "required": [ "id", "created_at", "updated_at", "peer_or_self_review_question_id", "peer_or_self_review_submission_id" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "number_data": { "type": ["number", "null"], "format": "float" }, "peer_or_self_review_question_id": { "type": "string", "format": "uuid" }, "peer_or_self_review_submission_id": { "type": "string", "format": "uuid" }, "text_data": { "type": ["string", "null"] }, "updated_at": { "type": "string", "format": "date-time" } } }, "PeerOrSelfReviewQuestionType": { "type": "string", "enum": ["Essay", "Scale"] }, "PeerOrSelfReviewSubmission": { "type": "object", "required": [ "id", "created_at", "updated_at", "user_id", "exercise_id", "course_id", "peer_or_self_review_config_id", "exercise_slide_submission_id" ], "properties": { "course_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "exercise_id": { "type": "string", "format": "uuid" }, "exercise_slide_submission_id": { "type": "string", "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "peer_or_self_review_config_id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "PeerOrSelfReviewSubmissionWithSubmissionOwner": { "allOf": [ { "$ref": "#/components/schemas/PeerOrSelfReviewSubmission" }, { "type": "object", "properties": { "submission_owner_user_id": { "type": ["string", "null"], "format": "uuid" } } } ], "description": "Same as PeerOrSelfReviewSubmission with optional submission owner (user who received the review). Used for \"given\" reviews." }, "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" ] }, "PeerReviewQueueEntry": { "type": "object", "required": [ "id", "created_at", "updated_at", "user_id", "exercise_id", "course_id", "receiving_peer_reviews_exercise_slide_submission_id", "received_enough_peer_reviews", "peer_review_priority", "removed_from_queue_for_unusual_reason" ], "properties": { "course_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "exercise_id": { "type": "string", "format": "uuid" }, "id": { "type": "string", "format": "uuid" }, "peer_review_priority": { "type": "integer", "format": "int32" }, "received_enough_peer_reviews": { "type": "boolean" }, "receiving_peer_reviews_exercise_slide_submission_id": { "type": "string", "format": "uuid" }, "removed_from_queue_for_unusual_reason": { "type": "boolean" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "PeerReviewWithQuestionsAndAnswers": { "type": "object", "required": [ "peer_or_self_review_submission_id", "peer_review_giver_user_id", "questions_and_answers" ], "properties": { "peer_or_self_review_submission_id": { "type": "string", "format": "uuid" }, "peer_review_giver_user_id": { "type": "string", "format": "uuid" }, "questions_and_answers": { "type": "array", "items": { "$ref": "#/components/schemas/PeerOrSelfReviewQuestionAndAnswer" } } } }, "PendingRole": { "type": "object", "required": ["id", "created_at", "updated_at", "user_email", "role", "expires_at"], "properties": { "course_id": { "type": ["string", "null"], "format": "uuid" }, "course_instance_id": { "type": ["string", "null"], "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "expires_at": { "type": "string", "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "role": { "$ref": "#/components/schemas/UserRole" }, "updated_at": { "type": "string", "format": "date-time" }, "user_email": { "type": "string" } } }, "PlanMemberWithDetails": { "type": "object", "required": ["id", "user_id", "email", "created_at"], "properties": { "created_at": { "type": "string", "format": "date-time" }, "email": { "type": "string", "format": "email" }, "first_name": { "type": ["string", "null"] }, "id": { "type": "string", "format": "uuid" }, "last_name": { "type": ["string", "null"] }, "user_id": { "type": "string", "format": "uuid" } } }, "PlaygroundExample": { "type": "object", "required": ["id", "created_at", "updated_at", "name", "url", "width", "data"], "properties": { "created_at": { "type": "string", "format": "date-time" }, "data": {}, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "name": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" }, "url": { "type": "string" }, "width": { "type": "integer", "format": "int32" } } }, "PlaygroundExampleData": { "type": "object", "required": ["name", "url", "width", "data"], "properties": { "data": {}, "name": { "type": "string" }, "url": { "type": "string" }, "width": { "type": "integer", "format": "int32" } } }, "PodDisruptionBudgetInfo": { "type": "object", "required": [ "name", "current_healthy", "desired_healthy", "disruptions_allowed", "expected_pods", "selector_labels" ], "properties": { "current_healthy": { "type": "integer", "format": "int32" }, "desired_healthy": { "type": "integer", "format": "int32" }, "disruptions_allowed": { "type": "integer", "format": "int32" }, "expected_pods": { "type": "integer", "format": "int32" }, "name": { "type": "string" }, "selector_labels": { "type": "object", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } } } }, "PodInfo": { "type": "object", "required": ["name", "phase", "labels"], "properties": { "labels": { "type": "object", "additionalProperties": { "type": "string" }, "propertyNames": { "type": "string" } }, "name": { "type": "string" }, "phase": { "type": "string" }, "ready": { "type": ["boolean", "null"] } } }, "PointMap": { "type": "object", "additionalProperties": { "type": "number", "format": "float" }, "propertyNames": { "type": "string", "format": "uuid" } }, "Points": { "type": "object", "required": ["chapter_points", "users", "user_chapter_points"], "properties": { "chapter_points": { "type": "array", "items": { "$ref": "#/components/schemas/ChapterScore" } }, "user_chapter_points": { "type": "object", "additionalProperties": { "$ref": "#/components/schemas/PointMap" }, "propertyNames": { "type": "string", "format": "uuid" } }, "users": { "type": "array", "items": { "$ref": "#/components/schemas/UserDetail" } } } }, "ProposalCount": { "type": "object", "required": ["pending", "handled"], "properties": { "handled": { "type": "integer", "format": "int32", "minimum": 0 }, "pending": { "type": "integer", "format": "int32", "minimum": 0 } } }, "ProposalStatus": { "type": "string", "enum": ["Pending", "Accepted", "Rejected"] }, "ReasoningEffortLevel": { "type": "string", "enum": ["none", "minimal", "low", "medium", "high", "xhigh"] }, "Regrading": { "type": "object", "required": [ "id", "created_at", "updated_at", "total_grading_progress", "user_points_update_strategy" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "error_message": { "type": ["string", "null"] }, "id": { "type": "string", "format": "uuid" }, "regrading_completed_at": { "type": ["string", "null"], "format": "date-time" }, "regrading_started_at": { "type": ["string", "null"], "format": "date-time" }, "total_grading_progress": { "$ref": "#/components/schemas/GradingProgress" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": ["string", "null"], "format": "uuid" }, "user_points_update_strategy": { "$ref": "#/components/schemas/UserPointsUpdateStrategy" } } }, "RegradingInfo": { "type": "object", "required": ["regrading", "submission_infos"], "properties": { "regrading": { "$ref": "#/components/schemas/Regrading" }, "submission_infos": { "type": "array", "items": { "$ref": "#/components/schemas/RegradingSubmissionInfo" } } } }, "RegradingSubmissionInfo": { "type": "object", "required": ["exercise_task_submission_id", "grading_before_regrading"], "properties": { "exercise_task_submission_id": { "type": "string", "format": "uuid" }, "grading_after_regrading": { "oneOf": [ { "type": "null" }, { "$ref": "#/components/schemas/ExerciseTaskGrading" } ] }, "grading_before_regrading": { "$ref": "#/components/schemas/ExerciseTaskGrading" } } }, "ReportReason": { "type": "string", "enum": ["Spam", "HarmfulContent", "AiGenerated"] }, "ResearchFormQuestionAnswer": { "type": "object", "required": [ "id", "user_id", "course_id", "research_form_question_id", "research_consent", "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" }, "research_consent": { "type": "boolean" }, "research_form_question_id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "ResetExercisesPayload": { "type": "object", "required": [ "user_ids", "exercise_ids", "reset_all_below_max_points", "reset_only_locked_peer_reviews" ], "properties": { "exercise_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } }, "reset_all_below_max_points": { "type": "boolean" }, "reset_only_locked_peer_reviews": { "type": "boolean" }, "threshold": { "type": ["number", "null"], "format": "double" }, "user_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } } } }, "ResetPasswordData": { "type": "object", "required": ["token", "new_password"], "properties": { "new_password": { "type": "string" }, "token": { "type": "string" } } }, "ResetPasswordTokenPayload": { "type": "object", "required": ["token"], "properties": { "token": { "type": "string" } } }, "ReviewingStage": { "type": "string", "description": "\nTells what stage of reviewing the user is currently in. Used for for peer review, self review, and manual review. If an exercise does not involve reviewing, the value of this stage will always be `NotStarted`.", "enum": [ "NotStarted", "PeerReview", "SelfReview", "WaitingForPeerReviews", "WaitingForManualGrading", "ReviewedAndLocked", "Locked" ] }, "Role": { "type": "object", "required": ["is_global", "role", "user_id"], "properties": { "course_id": { "type": ["string", "null"], "format": "uuid" }, "course_instance_id": { "type": ["string", "null"], "format": "uuid" }, "exam_id": { "type": ["string", "null"], "format": "uuid" }, "is_global": { "type": "boolean" }, "organization_id": { "type": ["string", "null"], "format": "uuid" }, "role": { "$ref": "#/components/schemas/UserRole" }, "user_id": { "type": "string", "format": "uuid" } } }, "RoleDomain": { "oneOf": [ { "type": "object", "required": ["tag"], "properties": { "tag": { "type": "string", "enum": ["Global"] } } }, { "type": "object", "required": ["id", "tag"], "properties": { "id": { "type": "string", "format": "uuid" }, "tag": { "type": "string", "enum": ["Organization"] } } }, { "type": "object", "required": ["id", "tag"], "properties": { "id": { "type": "string", "format": "uuid" }, "tag": { "type": "string", "enum": ["Course"] } } }, { "type": "object", "required": ["id", "tag"], "properties": { "id": { "type": "string", "format": "uuid" }, "tag": { "type": "string", "enum": ["CourseInstance"] } } }, { "type": "object", "required": ["id", "tag"], "properties": { "id": { "type": "string", "format": "uuid" }, "tag": { "type": "string", "enum": ["Exam"] } } } ] }, "RoleInfo": { "type": "object", "required": ["email", "role", "domain"], "properties": { "domain": { "$ref": "#/components/schemas/RoleDomain" }, "email": { "type": "string" }, "role": { "$ref": "#/components/schemas/UserRole" } } }, "RoleUser": { "type": "object", "required": ["user_id", "email", "role"], "properties": { "email": { "type": "string" }, "first_name": { "type": ["string", "null"] }, "last_name": { "type": ["string", "null"] }, "role": { "$ref": "#/components/schemas/UserRole" }, "user_id": { "type": "string", "format": "uuid" } } }, "SaveCourseDesignerScheduleRequest": { "type": "object", "required": ["stages"], "properties": { "name": { "type": ["string", "null"] }, "stages": { "type": "array", "items": { "$ref": "#/components/schemas/CourseDesignerScheduleStageInput" } } } }, "SearchRequest": { "type": "object", "required": ["query"], "properties": { "query": { "type": "string" } } }, "ServiceInfo": { "type": "object", "required": ["name", "ports"], "properties": { "cluster_ip": { "type": ["string", "null"] }, "name": { "type": "string" }, "ports": { "type": "array", "items": { "$ref": "#/components/schemas/ServicePortInfo" } } } }, "ServicePortInfo": { "type": "object", "required": ["port"], "properties": { "name": { "type": ["string", "null"] }, "port": { "type": "integer", "format": "int32" }, "protocol": { "type": ["string", "null"] }, "target_port": { "type": ["string", "null"] } } }, "SisuDescriptionResponse": { "type": "object", "required": ["course_description", "audience", "modules"], "properties": { "audience": { "type": "array", "items": { "type": "string" } }, "course_description": { "type": "string" }, "modules": { "type": "array", "items": { "$ref": "#/components/schemas/Module" } } } }, "StudentsByCountryTotalsResult": { "type": "object", "required": ["count"], "properties": { "count": { "type": "integer", "format": "int64" }, "country": { "type": ["string", "null"] } } }, "StudentsListPage": { "type": "object", "description": "A page of the student identity list plus the total number of pages for the current filters.", "required": ["data", "total_pages"], "properties": { "data": { "type": "array", "items": { "$ref": "#/components/schemas/CourseStudentListRow" } }, "total_pages": { "type": "integer", "format": "int32", "minimum": 0 } } }, "SuspectedCheaterStatus": { "type": "string", "description": "Review state of a suspected cheater.", "enum": ["Flagged", "ConfirmedCheating", "Dismissed"] }, "SuspectedCheaters": { "type": "object", "required": ["id", "user_id", "course_id", "created_at", "total_points", "status"], "properties": { "course_id": { "type": "string", "format": "uuid" }, "course_module_id": { "type": ["string", "null"], "format": "uuid", "description": "The module completion that triggered the flag. `None` only for legacy rows the backfill\ncouldn't map to a default module." }, "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "status": { "$ref": "#/components/schemas/SuspectedCheaterStatus" }, "total_duration_seconds": { "type": ["integer", "null"], "format": "int32" }, "total_points": { "type": "integer", "format": "int32" }, "updated_at": { "type": ["string", "null"], "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "SystemHealthStatus": { "type": "object", "required": ["status", "issues"], "properties": { "issues": { "type": "array", "items": { "type": "string" } }, "status": { "$ref": "#/components/schemas/HealthStatus" } } }, "TeacherDecisionType": { "type": "string", "enum": [ "FullPoints", "ZeroPoints", "CustomPoints", "SuspectedPlagiarism", "RejectAndReset" ] }, "TeacherGradingDecision": { "type": "object", "required": [ "id", "user_exercise_state_id", "created_at", "updated_at", "score_given", "teacher_decision" ], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "hidden": { "type": ["boolean", "null"] }, "id": { "type": "string", "format": "uuid" }, "justification": { "type": ["string", "null"] }, "score_given": { "type": "number", "format": "float" }, "teacher_decision": { "$ref": "#/components/schemas/TeacherDecisionType" }, "updated_at": { "type": "string", "format": "date-time" }, "user_exercise_state_id": { "type": "string", "format": "uuid" }, "user_id": { "type": ["string", "null"], "format": "uuid" } } }, "TeacherManualCompletion": { "type": "object", "required": ["user_id", "passed"], "properties": { "completion_date": { "type": ["string", "null"], "format": "date-time" }, "grade": { "type": ["integer", "null"], "format": "int32" }, "passed": { "type": "boolean" }, "user_id": { "type": "string", "format": "uuid" } } }, "TeacherManualCompletionRequest": { "type": "object", "required": ["course_module_id", "new_completions", "skip_duplicate_completions"], "properties": { "course_module_id": { "type": "string", "format": "uuid" }, "new_completions": { "type": "array", "items": { "$ref": "#/components/schemas/TeacherManualCompletion" } }, "skip_duplicate_completions": { "type": "boolean" } } }, "Term": { "type": "object", "required": ["id", "created_at", "updated_at", "term", "definition", "course_id"], "properties": { "course_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "definition": { "type": "string" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "term": { "type": "string" }, "updated_at": { "type": "string", "format": "date-time" } } }, "TermUpdate": { "type": "object", "required": ["term", "definition"], "properties": { "definition": { "type": "string" }, "term": { "type": "string" } } }, "ThresholdData": { "type": "object", "required": ["duration_seconds"], "properties": { "duration_seconds": { "type": "integer", "format": "int32" } } }, "TimeGranularity": { "type": "string", "enum": ["Year", "Month", "Day"] }, "UpdateCourseDesignerStageTaskRequest": { "type": "object", "properties": { "description": { "type": ["string", "null"] }, "is_completed": { "type": ["boolean", "null"] }, "title": { "type": ["string", "null"] } } }, "UploadResult": { "type": "object", "description": "Result of a image upload. Tells where the uploaded image can be retrieved from.", "required": ["url"], "properties": { "url": { "type": "string" } } }, "User": { "type": "object", "required": ["id", "created_at", "updated_at"], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "email_domain": { "type": ["string", "null"] }, "id": { "type": "string", "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" }, "upstream_id": { "type": ["integer", "null"], "format": "int32" } } }, "UserChapterLockingStatus": { "type": "object", "required": [ "id", "created_at", "updated_at", "user_id", "chapter_id", "course_id", "status" ], "properties": { "chapter_id": { "type": "string", "format": "uuid" }, "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" }, "status": { "$ref": "#/components/schemas/ChapterLockingStatus" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "UserChapterProgress": { "type": "object", "required": [ "user_id", "chapter_id", "chapter_number", "chapter_name", "points_obtained", "exercises_attempted" ], "properties": { "chapter_id": { "type": "string", "format": "uuid" }, "chapter_name": { "type": "string" }, "chapter_number": { "type": "integer", "format": "int32" }, "exercises_attempted": { "type": "integer", "format": "int64" }, "points_obtained": { "type": "number", "format": "double" }, "user_id": { "type": "string", "format": "uuid" } } }, "UserCompletionInformation": { "type": "object", "required": [ "course_module_completion_id", "course_name", "uh_course_code", "email", "enable_registering_completion_to_uh_open_university" ], "properties": { "course_module_completion_id": { "type": "string", "format": "uuid" }, "course_name": { "type": "string" }, "ects_credits": { "type": ["number", "null"], "format": "float" }, "email": { "type": "string" }, "enable_registering_completion_to_uh_open_university": { "type": "boolean" }, "uh_course_code": { "type": "string" } } }, "UserCourseProgress": { "type": "object", "required": [ "course_module_id", "course_module_name", "course_module_order_number", "score_given" ], "properties": { "attempted_exercises": { "type": ["integer", "null"], "format": "int32" }, "attempted_exercises_required": { "type": ["integer", "null"], "format": "int32" }, "course_module_id": { "type": "string", "format": "uuid" }, "course_module_name": { "type": "string" }, "course_module_order_number": { "type": "integer", "format": "int32" }, "score_given": { "type": "number", "format": "float" }, "score_maximum": { "type": ["integer", "null"], "format": "int32", "minimum": 0 }, "score_required": { "type": ["integer", "null"], "format": "int32" }, "total_exercises": { "type": ["integer", "null"], "format": "int32", "minimum": 0 } } }, "UserCourseSettings": { "type": "object", "required": [ "user_id", "course_language_group_id", "created_at", "updated_at", "current_course_id", "current_course_instance_id", "hidden" ], "properties": { "course_language_group_id": { "type": "string", "format": "uuid" }, "created_at": { "type": "string", "format": "date-time" }, "current_course_id": { "type": "string", "format": "uuid" }, "current_course_instance_id": { "type": "string", "format": "uuid" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "hidden": { "type": "boolean", "description": "Whether the user has hidden this course from their personal \"My courses\" list. Does not\naffect course progress." }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "UserCourseSubmissionTime": { "type": "object", "description": "A single submission's time, its exercise, and the module that exercise sits in (via its chapter).\nUsed to plot a user's submission activity within a course.", "required": ["created_at", "exercise_id"], "properties": { "course_module_id": { "type": ["string", "null"], "format": "uuid", "description": "Module the exercise's chapter belongs to; `None` for exercises not placed in a chapter." }, "created_at": { "type": "string", "format": "date-time" }, "exercise_id": { "type": "string", "format": "uuid" } } }, "UserDetail": { "type": "object", "required": ["user_id", "created_at", "updated_at", "email"], "properties": { "country": { "type": ["string", "null"] }, "created_at": { "type": "string", "format": "date-time" }, "email": { "type": "string" }, "email_communication_consent": { "type": ["boolean", "null"] }, "first_name": { "type": ["string", "null"] }, "last_name": { "type": ["string", "null"] }, "search_helper": { "type": ["string", "null"] }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "UserDetailsRequest": { "type": "object", "required": ["user_id", "course_ids"], "properties": { "course_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } }, "user_id": { "type": "string", "format": "uuid" } } }, "UserExerciseState": { "type": "object", "required": [ "id", "user_id", "exercise_id", "created_at", "updated_at", "grading_progress", "activity_progress", "reviewing_stage" ], "properties": { "activity_progress": { "$ref": "#/components/schemas/ActivityProgress" }, "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" }, "exercise_id": { "type": "string", "format": "uuid" }, "grading_progress": { "$ref": "#/components/schemas/GradingProgress" }, "id": { "type": "string", "format": "uuid" }, "reviewing_stage": { "$ref": "#/components/schemas/ReviewingStage" }, "score_given": { "type": ["number", "null"], "format": "float" }, "selected_exercise_slide_id": { "type": ["string", "null"], "format": "uuid" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "UserIdsPayload": { "type": "object", "description": "Body for the batch detail endpoints: the users of the current identity-list page.", "required": ["user_ids"], "properties": { "user_ids": { "type": "array", "items": { "type": "string", "format": "uuid" } } } }, "UserInfoPayload": { "type": "object", "required": ["email", "first_name", "last_name", "country", "email_communication_consent"], "properties": { "country": { "type": "string" }, "email": { "type": "string" }, "email_communication_consent": { "type": "boolean" }, "first_name": { "type": "string" }, "last_name": { "type": "string" } } }, "UserPointsUpdateStrategy": { "type": "string", "enum": ["CanAddPointsButCannotRemovePoints", "CanAddPointsAndCanRemovePoints"] }, "UserResearchConsent": { "type": "object", "required": ["id", "user_id", "research_consent", "created_at", "updated_at"], "properties": { "created_at": { "type": "string", "format": "date-time" }, "deleted_at": { "type": ["string", "null"], "format": "date-time" }, "id": { "type": "string", "format": "uuid" }, "research_consent": { "type": "boolean" }, "updated_at": { "type": "string", "format": "date-time" }, "user_id": { "type": "string", "format": "uuid" } } }, "UserRole": { "type": "string", "enum": [ "Reviewer", "Assistant", "Teacher", "Admin", "CourseOrExamCreator", "MaterialViewer", "TeachingAndLearningServices", "StatsViewer" ] }, "UserSuspectedCheaterInfo": { "type": "object", "description": "A user's suspected-cheater record in one course, paired with that course's duration threshold.\nRead-only, for the cross-course \"Completion review\" list on the user-details page.", "required": [ "course_id", "status", "total_points", "first_flagged_at", "threshold_seconds" ], "properties": { "course_id": { "type": "string", "format": "uuid" }, "first_flagged_at": { "type": "string", "format": "date-time", "description": "When first flagged in this course (record `created_at`, unchanged on re-flag)." }, "status": { "$ref": "#/components/schemas/SuspectedCheaterStatus" }, "threshold_seconds": { "type": "integer", "format": "int32", "description": "Threshold (seconds) of the module that triggered the flag; the student completed faster." }, "total_duration_seconds": { "type": ["integer", "null"], "format": "int32" }, "total_points": { "type": "integer", "format": "int32" } } }, "UserWithModuleCompletions": { "type": "object", "required": ["completed_modules", "email", "user_id"], "properties": { "completed_modules": { "type": "array", "items": { "$ref": "#/components/schemas/CourseModuleCompletionWithRegistrationInfo" } }, "email": { "type": "string" }, "first_name": { "type": ["string", "null"] }, "last_name": { "type": ["string", "null"] }, "user_id": { "type": "string", "format": "uuid" } } }, "VerbosityLevel": { "type": "string", "enum": ["low", "medium", "high"] } } }, "tags": [ { "name": "glossary", "description": "Glossary endpoints used by main-frontend" } ] }