{"openapi":"3.1.2","info":{"title":"SendPulse Education Public API","description":"Using the API for the Education service, you can integrate your system with online courses from SendPulse.\n\nRequests are limited to 100 per minute per user. Public API access depends on the user's tariff.\n","version":"1.0.0"},"servers":[{"url":"https:\/\/api.sendpulse.com\/edu\/public\/v1","description":"Production server"}],"tags":[{"name":"Courses","description":"Online courses created in the user's account. Use them to get course identifiers\nthat most other operations accept as `courseId`.\n"},{"name":"Course tariffs","description":"Tariffs (pricing plans) of a course: price, payment methods, renewal settings\nand the content and functionality available to students on the tariff.\n"},{"name":"Schools","description":"Schools of the user's account. A school groups courses and has its own domain and settings.\n"},{"name":"Students","description":"Students of the user's courses: enrollment and removal, search by course or audience,\nmarking as paid, changing course status and progress, and course statistics.\n"},{"name":"Students groups","description":"Groups that split students of a course, for example by stream or curator.\n"},{"name":"Tags","description":"Contact tags of the user's account. Tags are shared with SendPulse CRM and can be used\nto label and filter students.\n"},{"name":"Homeworks","description":"Homeworks submitted by students: the list of homeworks filtered by review status (awaiting review by default),\na single homework with the student's answer, and rating a homework.\n"},{"name":"Homework tasks","description":"Homework tasks attached to course lessons: creating, updating and deleting the task students have to complete.\n"},{"name":"Sections","description":"Sections (modules) of a course. Lessons, tests, forms and certificate sections are placed inside sections.\n"},{"name":"Lessons","description":"Lessons of a course and the course structure (sections with their lessons) as shown in the course constructor.\n"},{"name":"Tests","description":"Tests (quizzes) attached to a course, a section or a lesson, and their questions.\n"},{"name":"Forms","description":"Forms (questionnaires) placed in course sections, and their questions.\n"},{"name":"Certificate sections","description":"Course sections that issue a certificate to the student.\n"},{"name":"Domains","description":"Domains of the user's account and system domains that can be used to create a school subdomain.\n"}],"paths":{"\/courses":{"get":{"tags":["Courses"],"operationId":"listCourses","summary":"Get all courses for user","description":"Returns all courses of the user except blocked ones, without pagination.\n","responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CourseList"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"post":{"tags":["Courses"],"operationId":"createCourse","summary":"Create course","description":"Creates an inactive course in the school together with its default tariff.\nThe course language is the user's language and the LMS flag is taken from the school.\nThe `200` response is the course without a `data` wrapper.\n","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateCourseRequest"}}}},"responses":{"200":{"description":"OK \u2014 the course is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CourseDetails"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.schoolId` \u2014 \"School does not belong to user\" when the school does not exist or is not the user's;\n- `errors[\"New course\"]` \u2014 \"You cannot create a course due to tariff restrictions\" when the course limit of the user's tariff is reached.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{courseId}\/tariffs":{"get":{"tags":["Course tariffs"],"operationId":"listCourseTariffs","summary":"Get course tariffs","description":"Returns tariffs of the course sorted by `order`, both active and inactive, without pagination.\nThe response is a plain array without a `data` wrapper.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"ids[]","in":"query","required":false,"description":"Return only tariffs with these identifiers. Must be sent with brackets (`ids[]=1&ids[]=2`), a plain `ids=1` is not supported","style":"form","explode":true,"schema":{"type":"array","items":{"type":"integer"}},"example":[4521,4522]},{"name":"excludeIds[]","in":"query","required":false,"description":"Exclude tariffs with these identifiers. Must be sent with brackets (`excludeIds[]=1`), a plain `excludeIds=1` is not supported","style":"form","explode":true,"schema":{"type":"array","items":{"type":"integer"}},"example":[4520]},{"name":"status","in":"query","required":false,"description":"`1` \u2014 return only inactive tariffs","schema":{"type":"integer","enum":[1]},"example":1}],"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/CourseTariff"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `courseId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}":{"put":{"tags":["Courses"],"operationId":"updateCourse","summary":"Update course","description":"Replaces the editable settings of the course. Send the full set of fields: omitted `coverImage`, `passingScore`,\n`redirectUrl`, `failedRedirectUrl` and `groupId` are cleared, an omitted `isLinear` becomes `false`\nand an omitted `completionCriterion` becomes `lessonsCompleted`. `categoriesIds` is changed only when sent.\nThe `200` response is the course without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateCourseRequest"}}}},"responses":{"200":{"description":"OK \u2014 the course is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CourseDetails"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked, does not belong to the user or to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.groupId` is \"Group does not belong to school\"\nwhen the course group is not a group of the course's school.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Courses"],"operationId":"deleteCourse","summary":"Delete course","description":"Deletes the course: it gets the `blocked` status and is no longer returned by the API. The course page is unbound from the landing.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"responses":{"204":{"description":"No Content \u2014 the course is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked, does not belong to the user or to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/duplicate":{"post":{"tags":["Courses"],"operationId":"duplicateCourse","summary":"Duplicate course","description":"Creates an inactive copy of the course in the same school `{schoolId}`. The copy keeps the cover, passing score,\nlinear mode, completion criterion and course settings; dates, timezone and redirect URLs are not copied.\nCourse content (sections, lessons, tests, etc.) is copied in the background after the response.\nWith `copyPage: true` a new course page is created under `slug`.\nAvailable only on a paid tariff of the user. The `200` response is the new course without a `data` wrapper;\nits `courseSettings` are the settings of the source course (including the source `id` and `courseId`).\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user; the copy is created in this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Identifier of the course to copy. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DuplicateCourseRequest"}}}},"responses":{"200":{"description":"OK \u2014 the copy is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CourseDetails"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked, does not belong to the user or to the school `{schoolId}`, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.slug` \u2014 `cant_set_page_for_lms_course` when the source course is an LMS course, `slug_already_in_use` when the slug is taken in the school;\n- `errors[\"New course\"]` \u2014 \"You cannot create a course due to tariff restrictions\" when the course limit of the user's tariff is reached.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{courseId}\/batch\/copy":{"post":{"tags":["Courses"],"operationId":"batchCopyCourseContent","summary":"Copy course content to another course","description":"Copies the selected sections, lessons, tests, certificate sections and forms of the course `{courseId}`\nto the course `newCourseId`. Everything selected must belong to `{courseId}`.\nSections are copied with the content listed in their `lessonsIds`, `testsIds`, `certificateSectionsIds` and `formsIds`;\ntop-level lessons, tests, certificate sections and forms are copied into the section `newSectionId` of the target course.\n\nThe copy runs in the background: `200` with an empty array means it is queued, not finished.\nAvailable only on a paid tariff of the user.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Identifier of the source course. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BatchCopyCourseContentRequest"}}}},"responses":{"200":{"description":"OK \u2014 the copy is queued. The body is an empty JSON array","content":{"application\/json":{"schema":{"type":"array","maxItems":0,"items":[]},"example":[]}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the source or the target course does not exist or does not belong to the user, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- an item does not belong to the user or to `{courseId}` \u2014 \"The :attribute must belong to course.\" for the item key (e.g. `errors[\"sections.0.id\"]`, `errors[\"lessonsIds.0\"]`);\n- `errors.newSectionId` \u2014 \"The newSectionId must belong to the target course.\";\n- `errors.newCourseId` \u2014 `copy_to_course_error` when no sections are selected and the target course has no sections.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{courseId}\/batch\/access":{"post":{"tags":["Courses"],"operationId":"batchUpdateCourseContentAccess","summary":"Change status of course content in bulk","description":"Sets the status of the selected sections, lessons, tests, certificate sections and forms of the course.\nEvery group is optional; a group without `status` is left unchanged. `startDate` and `timezone` are used for the `planned` status.\n\nThe change runs in the background: `200` with an empty array means it is queued, not finished.\nAvailable only on a paid tariff of the user.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BatchUpdateCourseContentAccessRequest"}}}},"responses":{"200":{"description":"OK \u2014 the change is queued. The body is an empty JSON array","content":{"application\/json":{"schema":{"type":"array","maxItems":0,"items":[]},"example":[]}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist or does not belong to the user, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, an item that does not belong to the user or to the course\ngets \"The :attribute must belong to course.\" (e.g. `errors[\"sections.ids.0\"]`, `errors[\"forms.ids.0\"]`).\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{courseId}\/batch\/delete":{"delete":{"tags":["Courses"],"operationId":"batchDeleteCourseContent","summary":"Delete course content in bulk","description":"Deletes the selected sections, lessons, tests, certificate sections and forms of the course.\nThe identifiers are sent in the request body.\n\nThe deletion runs in the background: `200` with an empty array means it is queued, not finished.\nAvailable only on a paid tariff of the user.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/BatchDeleteCourseContentRequest"}}}},"responses":{"200":{"description":"OK \u2014 the deletion is queued. The body is an empty JSON array","content":{"application\/json":{"schema":{"type":"array","maxItems":0,"items":[]},"example":[]}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist or does not belong to the user, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, an item that does not belong to the user or to the course\ngets \"The :attribute must belong to course.\" (e.g. `errors[\"sectionsIds.0\"]`, `errors[\"certificateSectionIds.0\"]`).\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs":{"post":{"tags":["Course tariffs"],"operationId":"createCourseTariff","summary":"Create course tariff","description":"Creates a tariff of the course. The new tariff is never the main one and has no payment methods yet;\nadd them with `createPaymentMethod`. Available only on a paid tariff of the user.\nThe `201` response is the tariff without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CourseTariffRequest"}}}},"responses":{"201":{"description":"Created \u2014 the tariff is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ShortCourseTariff"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, does not belong to the user or to the school `{schoolId}`, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/order":{"put":{"tags":["Course tariffs"],"operationId":"reorderCourseTariffs","summary":"Set order of course tariffs","description":"Sets the display order of the course tariffs: the tariff at index `0` of `tariffs` gets the first position.\nReturns all tariffs of the course with their payment methods, accesses, settings and renewals, wrapped in `data`.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ReorderCourseTariffsRequest"}}}},"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CourseTariffDetailsList"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, does not belong to the user or to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors[\"tariffs.N\"]` is \"tariffs.N is invalid\"\nwhen the tariff does not belong to the course.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/accesses\/functionality\/{courseTariffId}":{"put":{"tags":["Course tariffs"],"operationId":"updateTariffFunctionalityAccess","summary":"Set functionality available on a tariff","description":"Replaces the list of functionality available to students on the tariff. An empty or omitted `data` removes all functionality.\nAvailable only on a paid tariff of the user. The response is a plain array without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateTariffFunctionalityAccessRequest"}}}},"responses":{"200":{"description":"OK \u2014 the functionality now available on the tariff","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/TariffFunctionality"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/accesses\/contents\/{courseTariffId}":{"put":{"tags":["Course tariffs"],"operationId":"updateTariffContentAccess","summary":"Set course content available on a tariff","description":"Replaces the list of course content (sections, lessons, tests, certificates, forms) available to students on the tariff.\n`data` is required; an empty array removes all content from the tariff.\nEvery `entityId` must be content of this course of the given `contentType`, otherwise `422` is returned.\nAvailable only on a paid tariff of the user. The response is a plain array without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateTariffContentAccessRequest"}}}},"responses":{"200":{"description":"OK \u2014 the content now available on the tariff","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/TariffContentAccess"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors (`data` is required and must be a list of at most 500 items,\n`contentType` is required for every item), `errors[\"data.N.entityId\"]` is returned when the entity\nis not content of this course of the given `contentType`.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/accesses\/entities":{"put":{"tags":["Course tariffs"],"operationId":"updateTariffsEntityAccess","summary":"Set course content available on several tariffs","description":"For every item of `data`, replaces the list of course content available on the tariff `tariffId` with `entities`\n(an empty `entities` removes all content from that tariff). Tariffs that are not listed are not changed.\nEvery `entityId` must be content of this course of the given `entityType`, otherwise `422` is returned.\nAt most 500 items in `data`, 500 `entities` per item and 500 entities in total per request.\nAvailable only on a paid tariff of the user.\n\nThe response is a plain array with one element per item of `data`, in the same order;\neach element is the array of content now available on that tariff (the tariff identifier is not repeated).\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateTariffsEntityAccessRequest"}}}},"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"type":"array","items":{"type":"array","items":{"$ref":"#\/components\/schemas\/TariffContentAccess"}}},"example":[[{"contentType":"lesson","entityId":90211},{"contentType":"test","entityId":5120}],[]]}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, does not belong to the user or to the school `{schoolId}`, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors[\"data.N.tariffId\"]` is returned when the tariff does not belong\nto the course, `errors[\"data.N.entities.M.entityId\"]` when the entity is not content of this course of the given\n`entityType`, and `errors[\"data\"]` when the limits of 500 items \/ 500 entities in total are exceeded.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/{courseTariffId}":{"put":{"tags":["Course tariffs"],"operationId":"updateCourseTariff","summary":"Update course tariff","description":"Updates the name, status, pricing type and redirect URLs of the tariff.\nThe tariff always stops being the main one after the update (`isMain` in the request is ignored).\nAvailable only on a paid tariff of the user. The response is the tariff without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CourseTariffRequest"}}}},"responses":{"200":{"description":"OK \u2014 the tariff is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ShortCourseTariff"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.pricingType` \u2014 \"A free tariff cannot have payment methods\", \"A one-time tariff cannot have payment methods with a recurring period\",\n  \"A subscription tariff must have a single payment method with a recurring period\" or\n  \"The pricing type of a started subscription tariff cannot be changed\";\n- `errors.courseTariffId` \u2014 \"The course must have at least 1 active tariff\" when the last active tariff is deactivated.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Course tariffs"],"operationId":"deleteCourseTariff","summary":"Delete course tariff","description":"Deletes the tariff. If the tariff has students, `courseTariffIdTo` is required and the students are moved to that tariff;\nif it has no students, `courseTariffIdTo` must not be sent.\nThe deletion runs in the background: `204` means it is queued, not finished.\nAvailable only on a paid tariff of the user.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Identifier of the tariff to delete. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"requestBody":{"required":false,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/DeleteCourseTariffRequest"}}}},"responses":{"204":{"description":"No Content \u2014 the deletion is queued"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.courseTariffIdTo` \u2014 required when the tariff has students and must be missing when it has none;\n  \"courseTariffIdTo is invalid\" when the target tariff is not a tariff of the course, \"Tariff is not active\" when it is inactive;\n- `errors.courseTariffId` \u2014 \"The course must have at least 1 active tariff\" or \"A subscription tariff with active subscribers cannot be deleted\".\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/{courseTariffId}\/duplicate":{"post":{"tags":["Course tariffs"],"operationId":"duplicateCourseTariff","summary":"Duplicate course tariff","description":"Creates a copy of the tariff in the same course. Available only on a paid tariff of the user.\nThe `201` response is the new tariff without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Identifier of the tariff to copy. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"responses":{"201":{"description":"Created \u2014 the copy is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ShortCourseTariff"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/{courseTariffId}\/settings":{"put":{"tags":["Course tariffs"],"operationId":"updateCourseTariffSettings","summary":"Update tariff availability settings","description":"Creates or replaces the availability settings of the tariff: the sale period, the student quota and whether\ncontent that is not available on the tariff is shown to students. Omitted optional fields are cleared.\nThe response is the settings object without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateCourseTariffSettingsRequest"}}}},"responses":{"200":{"description":"OK \u2014 the settings are saved","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TariffSettings"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.quota` is \"Quota cannot be less than the number of students on the plan.\"\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/{courseTariffId}\/tariff-renewal":{"post":{"tags":["Course tariffs"],"operationId":"createTariffRenewal","summary":"Create tariff renewal","description":"Adds a paid access extension to the tariff: the student pays `amount` to extend their access by `days`.\nThe `201` response is the renewal without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TariffRenewalRequest"}}}},"responses":{"201":{"description":"Created \u2014 the renewal is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TariffRenewalItem"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/{courseTariffId}\/tariff-renewal\/{id}":{"put":{"tags":["Course tariffs"],"operationId":"updateTariffRenewal","summary":"Update tariff renewal","description":"Replaces all fields of the renewal; omitted optional fields are cleared.\nThe response is the renewal without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521},{"name":"id","in":"path","required":true,"description":"Renewal identifier. The renewal must belong to the tariff","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":702}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TariffRenewalRequest"}}}},"responses":{"200":{"description":"OK \u2014 the renewal is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TariffRenewalItem"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course, the tariff or the renewal does not exist or does not belong to the user, to the school `{schoolId}`, to the course or to the tariff (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`id` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Course tariffs"],"operationId":"deleteTariffRenewal","summary":"Delete tariff renewal","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521},{"name":"id","in":"path","required":true,"description":"Renewal identifier. The renewal must belong to the tariff","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":702}],"responses":{"204":{"description":"No Content \u2014 the renewal is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course, the tariff or the renewal does not exist or does not belong to the user, to the school `{schoolId}`, to the course or to the tariff (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`id` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/{courseTariffId}\/access-restriction-settings":{"put":{"tags":["Course tariffs"],"operationId":"updateTariffAccessRestriction","summary":"Set course access duration for a tariff","description":"Limits the access of students on the tariff either to `restrictedDays` days after enrollment\nor until the fixed moment `restrictedToDate` (with `timezone`); the two are mutually exclusive.\nOne of them must be present: an explicit `null` removes the limit, an empty body is rejected with `422`.\nOn a free user tariff the restriction can only be changed if it already exists.\nThe response is the restriction without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateTariffAccessRestrictionRequest"}}}},"responses":{"200":{"description":"OK \u2014 the restriction is saved","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TariffAccessRestriction"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.courseTariffId` \u2014 \"Prohibited on free plan\" when the user's tariff is free and the tariff has no restriction yet;\n- `errors.restrictedDays` \u2014 \"The restricted days field must be present.\" when neither `restrictedDays` nor `restrictedToDate` is sent;\n- `errors.restrictedDays` \/ `errors.restrictedToDate` \u2014 both fields are sent (\"\u2026 must be missing when \u2026 is present.\");\n- `errors.restrictedToDate` \u2014 the date is in the past (\"The restricted to date field must be a date after or equal to now.\");\n- `errors.timezone` \u2014 `restrictedToDate` is sent without `timezone`, or the timezone is not a valid IANA identifier.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/{courseTariffId}\/advertising-text":{"put":{"tags":["Course tariffs"],"operationId":"upsertTariffAdvertisingText","summary":"Set tariff advertising text","description":"Creates or replaces the advertising text of the tariff. The response is the text without a `data` wrapper.","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpsertTariffAdvertisingTextRequest"}}}},"responses":{"200":{"description":"OK \u2014 the text is saved","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TariffAdvertisingText"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Course tariffs"],"operationId":"deleteTariffAdvertisingText","summary":"Delete tariff advertising text","description":"Removes the advertising text of the tariff. Deleting a text that does not exist also returns `204`.","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"responses":{"204":{"description":"No Content \u2014 the text is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/{courseTariffId}\/payment-method":{"post":{"tags":["Course tariffs"],"operationId":"createPaymentMethod","summary":"Add payment method to a tariff","description":"Adds a payment method to the tariff. `paymentId` selects one of the payment systems connected in the user's account;\nthe method name, currency and provider are taken from it.\nA free tariff cannot have payment methods, and a subscription tariff can have only one, with `recurringMode`.\nAvailable only on a paid tariff of the user. The `201` response is the payment method without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreatePaymentMethodRequest"}}}},"responses":{"201":{"description":"Created \u2014 the payment method is added","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TariffPaymentMethod"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the tariff does not exist, does not belong to the user, to the school `{schoolId}` or to the course, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed (only the first error is returned). Besides field errors:\n- `errors.paymentId` \u2014 `payment.invalid` when the payment system is not connected in the user's account;\n- `errors.courseTariffId` \u2014 \"It is forbidden to add payment methods to the free tariff\" or \"A subscription tariff can have only one payment method\";\n- `errors.recurringMode` \u2014 required for a subscription tariff and prohibited for other tariffs.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/tariffs\/{courseTariffId}\/payment-method\/{paymentId}":{"put":{"tags":["Course tariffs"],"operationId":"updatePaymentMethod","summary":"Update payment method","description":"Changes the price, fiscal receipt code and description of the payment method; only the sent fields are changed.\nThe payment system and `recurringMode` cannot be changed. The response is the payment method without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521},{"name":"paymentId","in":"path","required":true,"description":"Payment method identifier (`id` of the payment method, not the payment system key). The payment method must belong to the tariff","schema":{"type":"integer","minimum":1},"example":3920}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdatePaymentMethodRequest"}}}},"responses":{"200":{"description":"OK \u2014 the payment method is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/TariffPaymentMethod"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course, the tariff or the payment method does not exist or does not belong to the user, to the school `{schoolId}`, to the course or to the tariff (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.paymentId` \u2014 `payment.invalid` when the payment system is not connected in the user's account;\n- `errors.price` \u2014 \"The payment method of a started subscription tariff cannot be changed\".\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Course tariffs"],"operationId":"deletePaymentMethod","summary":"Delete payment method","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"courseTariffId","in":"path","required":true,"description":"Tariff identifier. The tariff must belong to the course","schema":{"type":"integer","minimum":1},"example":4521},{"name":"paymentId","in":"path","required":true,"description":"Payment method identifier (`id` of the payment method). The payment method must belong to the tariff","schema":{"type":"integer","minimum":1},"example":3920}],"responses":{"204":{"description":"No Content \u2014 the payment method is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course or the payment method does not exist or does not belong to the user, to the school `{schoolId}` or to the tariff (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/section":{"get":{"tags":["Sections"],"operationId":"listSections","summary":"List sections","description":"Returns all not deleted sections of the course, sorted by `order` (then by `id`).\nThe response is a plain array of sections without a `data` wrapper; a course without sections returns `[]`.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"responses":{"200":{"description":"OK \u2014 sections of the course","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/Section"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, does not belong to the user or to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"post":{"tags":["Sections"],"operationId":"createSection","summary":"Create section","description":"The `200` response is the section without a `data` wrapper.","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateSectionRequest"}}}},"responses":{"200":{"description":"OK \u2014 the section is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Section"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.courseId` is returned when the course does not belong to the user,\nand `errors.timezone` \/ `errors.preview` \u2014 \"Setting \u2026 is not allowed for the free tariff.\" when the user's tariff is free.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/section\/{sectionId}":{"put":{"tags":["Sections"],"operationId":"updateSection","summary":"Update section","description":"Replaces all fields of the section; omitted optional fields are cleared and an omitted `status` becomes `opened`.\nThe section cannot be moved to another course. The response is the section without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"sectionId","in":"path","required":true,"description":"Section identifier. The section must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":8801}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateSectionRequest"}}}},"responses":{"200":{"description":"OK \u2014 the section is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Section"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the section does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`sectionId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Sections"],"operationId":"deleteSection","summary":"Delete section","description":"The section gets the `deleted` status and is no longer shown.","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"sectionId","in":"path","required":true,"description":"Section identifier. The section must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":8801}],"responses":{"204":{"description":"No Content \u2014 the section is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the section does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`sectionId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/lesson":{"post":{"tags":["Lessons"],"operationId":"createLesson","summary":"Create lesson","description":"The `200` response is the lesson without a `data` wrapper.","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateLessonRequest"}}}},"responses":{"200":{"description":"OK \u2014 the lesson is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Lesson"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, does not belong to the user or to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.sectionId` is returned when the section is not a section of the course,\nand `errors.timezone` \/ `errors.preview` \/ `errors.minCompletionTime` \u2014 \"Setting \u2026 is not allowed for the free tariff.\" when the user's tariff is free.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/lesson\/{lessonId}":{"put":{"tags":["Lessons"],"operationId":"updateLesson","summary":"Update lesson","description":"Replaces all fields of the lesson; omitted optional fields are cleared and an omitted `status` becomes `opened`.\nThe lesson can be moved to another section of the same course with `sectionId`.\nThe response is the lesson without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"lessonId","in":"path","required":true,"description":"Lesson identifier. The lesson must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":90211}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateLessonRequest"}}}},"responses":{"200":{"description":"OK \u2014 the lesson is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Lesson"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the lesson does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`lessonId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed (only the first error is returned)."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Lessons"],"operationId":"deleteLesson","summary":"Delete lesson","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"lessonId","in":"path","required":true,"description":"Lesson identifier. The lesson must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":90211}],"responses":{"204":{"description":"No Content \u2014 the lesson is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the lesson does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`lessonId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/lessons":{"get":{"tags":["Lessons"],"operationId":"listCourseSectionsWithLessons","summary":"Get course structure","description":"Returns the sections of the course (except deleted ones) with their lessons, as shown in the course constructor.\nLesson content is not included; use `listCourseLessonsContent` for it.\nThe filters narrow down sections and lessons; `rating` and `access` apply to sections only when `module` is `section`.\nThe response is a plain array without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"dateFrom","in":"query","required":false,"description":"Only sections and lessons created at or after this moment","schema":{"type":"string","format":"date"},"example":"2026-01-01"},{"name":"dateTo","in":"query","required":false,"description":"Only sections and lessons created at or before this moment","schema":{"type":"string","format":"date"},"example":"2026-12-31"},{"name":"rating","in":"query","required":false,"description":"Only lessons (and, with `module=section`, sections) whose average student rating is between `rating - 1` and `rating`","schema":{"type":"integer","minimum":1,"maximum":5},"example":5},{"name":"access","in":"query","required":false,"description":"Only lessons (and, with `module=section`, sections) with this status. Unknown values are ignored","schema":{"type":"string","enum":["closed","opened","planned","hidden"]},"example":"opened"},{"name":"module","in":"query","required":false,"description":"Entity type the `rating` and `access` filters are applied to","schema":{"type":"string","enum":["section","lesson","test"]},"example":"section"}],"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/CourseStructureSection"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, does not belong to the user or to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/courses\/{schoolId}\/{courseId}\/lessons\/content":{"get":{"tags":["Lessons"],"operationId":"listCourseLessonsContent","summary":"Get content of all course lessons","description":"Returns the content blocks of every lesson of the course except deleted ones, without pagination.","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`, and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/LessonContentList"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, does not belong to the user or to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/{schoolId}\/{courseId}\/tests":{"post":{"tags":["Tests"],"operationId":"createTest","summary":"Create test","description":"Creates a test without questions; add them with `saveTestQuestions`.\nNote that this path has no `\/courses` prefix. The `200` response is the test without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateTestRequest"}}}},"responses":{"200":{"description":"OK \u2014 the test is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Test"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.courseId` is returned when the course does not belong to the user,\n`errors.relatedEntityId` when the related entity is not the user's, and paid-only fields\n(`timezone`, `preview`, `questionsLimit`, `showAnswersAfterCompletion`, `saveBestResult`) get\n\"Setting \u2026 is not allowed for the free tariff.\" when the user's tariff is free.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/{schoolId}\/{courseId}\/tests\/{testId}":{"put":{"tags":["Tests"],"operationId":"updateTest","summary":"Update test","description":"Replaces all settings of the test; omitted optional fields are cleared. Questions are not changed.\nThe response is the test without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"testId","in":"path","required":true,"description":"Test identifier. The test must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":5120}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateTestRequest"}}}},"responses":{"200":{"description":"OK \u2014 the test is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Test"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the test does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`testId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Tests"],"operationId":"deleteTest","summary":"Delete test","description":"The test gets the `blocked` status; its questions are blocked in the background.","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"testId","in":"path","required":true,"description":"Test identifier. The test must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":5120}],"responses":{"204":{"description":"No Content \u2014 the test is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the test does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`testId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/{schoolId}\/{courseId}\/tests\/{testId}\/questions":{"post":{"tags":["Tests"],"operationId":"saveTestQuestions","summary":"Save test questions","description":"Replaces the full list of questions of the test. A question with `tmpId` is created; a question without `tmpId`\nupdates the existing question `id`. Existing questions that are not in the list are removed, and the order of\nthe list becomes the order of the questions. Answer variants are numbered from `0` in the order they are sent.\nRemoved questions disappear from the test immediately; the cleanup of students' running attempts runs\nin the background shortly after the response. The `id` of a removed question cannot be sent again;\n`id` values must be unique within one request.\n\nThe response is a plain array of the saved questions without a `data` wrapper;\n`tempId` from the request is returned to match new questions with their identifiers.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"testId","in":"path","required":true,"description":"Test identifier. The test must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":5120}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SaveTestQuestionsRequest"}}}},"responses":{"200":{"description":"OK \u2014 the questions are saved","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/TestQuestion"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the test does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`testId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors[\"questions.N.id\"]` \u2014 \"The question number \u2026 does not belong to the test\";\n- `errors[\"questions.N.variants.M.contentType\"]` \u2014 `validation.paid_tariff_required` for media variants on a free user tariff.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/{schoolId}\/{courseId}\/form":{"post":{"tags":["Forms"],"operationId":"createForm","summary":"Create form","description":"Creates a form without questions in a section of the course; add questions with `saveFormQuestions`.\nNote that this path has no `\/courses` prefix. The `201` response is wrapped in `data`.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SaveFormRequest"}}}},"responses":{"201":{"description":"Created \u2014 the form is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/FormResponse"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, does not belong to the user or to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.sectionId` is returned when the section is not a section of the course,\nand `errors.timezone` \u2014 \"Setting timezone is not allowed for the free tariff.\" when the user's tariff is free.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/{schoolId}\/{courseId}\/form\/{formId}":{"put":{"tags":["Forms"],"operationId":"updateForm","summary":"Update form","description":"Replaces all settings of the form; omitted optional fields are cleared. Questions are not changed.\nThe response is wrapped in `data`.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"formId","in":"path","required":true,"description":"Form identifier. The form must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":2210}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SaveFormRequest"}}}},"responses":{"200":{"description":"OK \u2014 the form is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/FormResponse"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the form does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`formId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Forms"],"operationId":"deleteForm","summary":"Delete form","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"formId","in":"path","required":true,"description":"Form identifier. The form must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":2210}],"responses":{"204":{"description":"No Content \u2014 the form is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the form does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`formId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/{schoolId}\/{courseId}\/form\/{formId}\/questions":{"post":{"tags":["Forms"],"operationId":"saveFormQuestions","summary":"Save form questions","description":"Replaces the full list of questions of the form. A question without `id` is created, a question with `id` is updated;\nexisting questions that are not in the list are deleted.\nThe answer type of a question that already has student answers cannot be changed.\nThe response wraps the saved questions in `questions`.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"formId","in":"path","required":true,"description":"Form identifier. The form must belong to the user and to the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":2210}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SaveFormQuestionsRequest"}}}},"responses":{"200":{"description":"OK \u2014 the questions are saved","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/FormQuestionList"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the form does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId`\/`formId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed, including an attempt to change the answer type of a question that already has student answers,\nand `errors[\"questions.N.id\"]` when the question `id` is not a question of the form `{formId}`.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/{schoolId}\/{courseId}\/certificate-section":{"post":{"tags":["Certificate sections"],"operationId":"createCertificateSection","summary":"Create certificate section","description":"Creates a certificate section in a section of the course. Either `certificateId` or `certificatePath` must be set.\nAvailable only on a paid tariff of the user. Note that this path has no `\/courses` prefix.\nThe `201` response is wrapped in `data`.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the school `{schoolId}`; it must equal `courseId` in the body","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateCertificateSectionRequest"}}}},"responses":{"201":{"description":"Created \u2014 the certificate section is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CertificateSectionResponse"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not belong to the school `{schoolId}`, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.courseId`, `errors.sectionId` and `errors.certificateId` are returned\nwhen the course, the section or the certificate does not belong to the user, or the section is not a section of the course.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"put":{"tags":["Certificate sections"],"operationId":"updateCertificateSection","summary":"Update certificate section","description":"Replaces all fields of the certificate section. Unlike other update operations, the identifier of the certificate section\nis sent in the body (`id`), not in the path. Available only on a paid tariff of the user.\nThe response is wrapped in `data`.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the school `{schoolId}`, and the certificate section `id` must belong to this course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateCertificateSectionRequest"}}}},"responses":{"200":{"description":"OK \u2014 the certificate section is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CertificateSectionResponse"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the certificate section does not exist or does not belong to the user or to the course, the course does not belong to the school `{schoolId}`, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/{schoolId}\/{courseId}\/certificate-section\/{certificateSectionId}":{"delete":{"tags":["Certificate sections"],"operationId":"deleteCertificateSection","summary":"Delete certificate section","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"certificateSectionId","in":"path","required":true,"description":"Certificate section identifier. The certificate section must belong to the user and to the course","schema":{"type":"integer","minimum":1},"example":1305}],"responses":{"204":{"description":"No Content \u2014 the certificate section is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the certificate section does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/schools":{"get":{"tags":["Schools"],"operationId":"listSchools","summary":"Get list of schools","description":"Returns all schools of the user sorted by `order`, without pagination. The response is a plain array without a `data` wrapper.","responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/School"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"post":{"tags":["Schools"],"operationId":"createSchool","summary":"Create school","description":"Creates an inactive school with a new site on the subdomain `domainName` of the system domain `systemDomainId`\n(see `listSystemDomains` and `checkSubdomainName`). The number of schools is limited by the user's tariff.\nThe `200` response is the school without a `data` wrapper.\n","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateSchoolRequest"}}}},"responses":{"200":{"description":"OK \u2014 the school is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SchoolDetails"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the school limit of the user's tariff is reached (`ErrorList`), or a common access error (`ErrorResponse`)."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.systemDomainId` \u2014 \"System domain id invalid!\" when the system domain is not available;\n- `errors.domainName` \u2014 \"Domain name invalid!\" when the subdomain is already taken;\n- `errors.error` \u2014 \"Domain cannot be created\" (or the site service errors) when the school site cannot be created.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/schools\/order":{"put":{"tags":["Schools"],"operationId":"reorderSchools","summary":"Set order of schools","description":"Sets the display order of the user's schools. All schools of the user must be listed, and the user must have at least two.\nReturns all schools sorted by the new order, as a plain array without a `data` wrapper.\n","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ReorderSchoolsRequest"}}}},"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/School"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.order` \u2014 \"You need at least 2 schools to reorder them\" or\n  \"The number of schools in the order does not match the number of schools in the user\";\n- `errors[\"order.N.id\"]` \u2014 \"School does not belong to user\".\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/schools\/{schoolId}":{"put":{"tags":["Schools"],"operationId":"updateSchool","summary":"Update school","description":"Updates the school name, students name, LMS flag and status. `studentsName` is cleared when omitted,\n`isLms` can only be switched on, and an omitted `status` sets the school to `inactive`.\nThe response is the school without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateSchoolRequest"}}}},"responses":{"200":{"description":"OK \u2014 the school is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SchoolDetails"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the school does not exist or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}},"delete":{"tags":["Schools"],"operationId":"deleteSchool","summary":"Delete school","description":"Deletes the school together with all its courses and unbinds the school page from the landing.","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The school must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307}],"responses":{"204":{"description":"No Content \u2014 the school is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the school does not exist or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/domains":{"get":{"tags":["Domains"],"operationId":"listDomains","summary":"Get domains of the user","description":"Returns all domains of the user's account, without pagination. The response is a plain array without a `data` wrapper.","responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/Domain"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/domains\/available":{"get":{"tags":["Domains"],"operationId":"listSystemDomains","summary":"Get system domains","description":"Returns the system domains on which a school subdomain can be created (`systemDomainId` for `createSchool`).\nThe response is a plain array without a `data` wrapper.\n","responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/SystemDomain"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/domains\/{name}\/{systemDomainId}\/check":{"get":{"tags":["Domains"],"operationId":"checkSubdomainName","summary":"Check that a subdomain is free","description":"Checks whether the subdomain `name` is still free on the system domain `systemDomainId`.\nIf the site service rejects the check for another reason, its HTTP status and message are returned as `ErrorResponse`.\n","parameters":[{"name":"name","in":"path","required":true,"description":"Subdomain name to check","schema":{"type":"string","pattern":"^[A-Za-z0-9-]{1,63}$"},"example":"coding-school"},{"name":"systemDomainId","in":"path","required":true,"description":"System domain identifier (`systemDomainId` from `listSystemDomains`)","schema":{"type":"integer","minimum":0},"example":1}],"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SubdomainAvailability"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `name` does not match `[A-Za-z0-9-]{1,63}` or `systemDomainId` is not a number."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students":{"post":{"tags":["Students"],"operationId":"createStudent","summary":"Create student","description":"Creates a student in the course's school and enrolls them on the course.\nIf an active student with this email already exists in the school, that student is enrolled instead,\nand their name, language and marketing consent are not changed.\nIf the student is already on the course, nothing is enrolled and `409` is returned.\nThe `201` response is the student object without a `data` wrapper.\n","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateStudentRequest"}}}},"responses":{"201":{"description":"Created \u2014 the student is enrolled on the course","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/Student"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"409":{"description":"The student is already on the course. Nothing is enrolled and the student stays on their current tariff;\nuse the change-tariff endpoint to move them.\n","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/StudentAlreadyOnCourse"}}}},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.availableSlots` is returned when the user's tariff has no free student slots:\n`{\"message\": \"It is forbidden to create students due tariff restrictions. Available slots: 0\", \"errors\": {\"availableSlots\": [\"It is forbidden to create students due tariff restrictions. Available slots: 0\"]}}`.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students\/auditory":{"post":{"tags":["Students"],"operationId":"searchAuditory","summary":"Search students across all courses","description":"Returns active students of the user across all courses, with the courses each student is on.\nAll filters are combined with AND. A student matches a course-level filter if any of their courses matches it.\n`meta.total` is the number of matches before pagination.\n","requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SearchAuditoryRequest"}}}},"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/AuditoryStudentList"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students\/course-statistics\/{studentId}":{"get":{"tags":["Students"],"operationId":"getStudentCourseStatistics","summary":"Get student course statistics","description":"Returns the student's progress on all their courses grouped by school: sections, lessons, tests,\nhomeworks, forms and certificates, plus the student's groups and responsible users.\nBlocked courses are not included.\n","parameters":[{"name":"studentId","in":"path","required":true,"description":"Student identifier. The student must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":7712345}],"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/StudentCourseStatisticsResponse"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the student does not exist or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `studentId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students\/{studentId}":{"delete":{"tags":["Students"],"operationId":"deleteStudent","summary":"Delete student from school","description":"Permanently deletes the student from the school and revokes their access tokens.\nBlocked students cannot be deleted. A repeated request returns `422`, because the student no longer exists.\n","parameters":[{"name":"studentId","in":"path","required":true,"description":"Student identifier. The student must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":7712345}],"responses":{"204":{"description":"No Content \u2014 the student is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `studentId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed:\n- the student does not exist (including an already deleted one) or does not belong to the user \u2014\n  `{\"message\": \"studentId.invalid\", \"errors\": {\"studentId\": [\"studentId.invalid\"]}}`;\n- the student is blocked \u2014\n  `{\"message\": \"Blocked student cannot be deleted.\", \"errors\": {\"student\": [\"Blocked student cannot be deleted.\"]}}`.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students\/{studentId}\/{courseId}":{"delete":{"tags":["Students"],"operationId":"removeStudentFromCourse","summary":"Delete student from course","description":"Removes the student from the course. The student stays in the school and on other courses.","parameters":[{"name":"studentId","in":"path","required":true,"description":"Student identifier. The student must belong to the user","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":7712345},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"responses":{"204":{"description":"No Content \u2014 the student is removed from the course"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the student or the course does not exist or does not belong to the user, or the course is blocked (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 the student is not on the course, or `studentId`\/`courseId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students\/by-course\/{courseId}":{"post":{"tags":["Students"],"operationId":"searchCourseStudents","summary":"Search students of a course","description":"Returns active students of the course that match the filters, with `offset`\/`limit` pagination.\nAll filters are combined with AND. `meta.total` is the number of matches before pagination.\n\n`meta.searchString` encodes the applied filters. Send it back as `searchString` to repeat the same search,\nor pass it to `markStudentsAsPaid`. When `searchString` is set, all other fields are ignored\n(but still validated) and the course is taken from the encoded filter; `{courseId}` is used only for the access check.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/SearchCourseStudentsRequest"}}}},"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CourseStudentList"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.progress` \u2014 \"You cannot set progress due to tariff restrictions.\" when the user's tariff is free;\n- `errors.searchString` \u2014 `validation.invalid` when `searchString` cannot be decoded;\n- `errors.offset` \/ `errors.limit` \u2014 `validation.required` when the decoded `searchString` has no `offset` or `limit`.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students\/{courseId}\/mark-as-paid":{"post":{"tags":["Students"],"operationId":"markStudentsAsPaid","summary":"Mark students as paid","description":"Marks the course tariff of the selected students as paid. The operation runs in the background:\n`204` means it is queued, not finished.\nOnly students who belong to the user, are on a paid tariff of the course and have not paid yet are changed;\nother students are skipped without an error.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/MarkStudentsAsPaidRequest"}}}},"responses":{"204":{"description":"No Content \u2014 the operation is queued"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students\/{courseId}\/change-status":{"post":{"tags":["Students"],"operationId":"changeStudentCourseStatus","summary":"Change student course completion status","description":"Sets the student's completion status on the course. Setting `certificated` makes the course certificate\navailable to the student, exactly as changing the status in the interface does. Repeating the same status is idempotent.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ChangeStudentCourseStatusRequest"}}}},"responses":{"204":{"description":"No Content \u2014 the status is changed"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 the student is not on the course, or `courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.studentId` is\n\"Student does not have a tariff\" when the student has no tariff on the course.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students\/{courseId}\/change-progress":{"post":{"tags":["Students"],"operationId":"changeStudentCourseProgress","summary":"Change student progress on lessons and tests","description":"Marks lessons and tests of the course as passed or not passed for the student.\nAt least one lesson or test identifier must be set in `passed` or `notPassed`.\nEvery identifier must belong to the course, and the same identifier must not be in both groups;\notherwise the whole request is rejected with `422` and nothing is changed.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ChangeStudentCourseProgressRequest"}}}},"responses":{"204":{"description":"No Content \u2014 the progress is changed"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 the student is not on the course, or `courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.passed` \u2014 \"At least one lesson or test identifier must be provided in passed or notPassed.\";\n- `errors[\"passed.lessons\"]` \/ `errors[\"passed.tests\"]` \u2014 the same identifier is in `passed` and `notPassed`.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/students\/{courseId}\/update-availability-date":{"post":{"tags":["Students"],"operationId":"updateStudentsAvailabilityDate","summary":"Set or extend students' course access date","description":"Sets the moment until which the selected students can access the course. The stored value is returned\nas `courseAvailableDate` by `getStudentCourseStatistics`, `searchCourseStudents` and `searchAuditory`.\nStudents are selected by `ids` or `searchString` \u2014 exactly one of them must be set.\n\nExactly one of `availabilityDate` or `extendDays` must be set:\n- `availabilityDate` \u2014 the field must be present; an explicit `null` removes the date (unlimited access).\n  A missing field is rejected with `422`, so a misspelled field can never revoke access by accident.\n  The date is converted to UTC before saving; `timezone` is required and stored for display only.\n- `extendDays` \u2014 adds `N` days to the student's current access date when it is in the future,\n  otherwise `N` days from now; computed per student. `timezone` is optional: when omitted,\n  the student's current timezone is kept.\n\nStudents who are not enrolled on the course or do not belong to the user are skipped without an error.\nAn access date in the past means the access is already closed.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateStudentsAvailabilityDateRequest"}}}},"responses":{"204":{"description":"No Content \u2014 the date is set"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the course does not exist, is blocked or does not belong to the user, or the user's tariff is free (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors:\n- `errors.availabilityDate` \u2014 \"The availability date field must be present.\" when neither `availabilityDate` nor `extendDays` is sent,\n  or \"The availability date field must be missing.\" when both are sent;\n- `errors.extendDays` \u2014 \"The extend days field must be missing when availability date is present.\" when both are sent;\n- `errors.ids` \/ `errors.searchString` \u2014 both are sent, or neither is sent, or `ids` has more than 500 items;\n- `errors[\"ids.N\"]` \/ `errors.extendDays` \u2014 the value is not a JSON integer;\n- `errors.timezone` \u2014 `availabilityDate` is sent without `timezone`, or the timezone is not a valid IANA identifier.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/groups\/{courseId}":{"get":{"tags":["Students groups"],"operationId":"listCourseGroups","summary":"List students groups by course","description":"Returns all student groups of the course, without pagination.\nThe response is a plain array without a `data` wrapper.\n","parameters":[{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the user and must not be blocked","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571}],"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/StudentGroup"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `courseId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed \u2014 the course does not exist, is blocked or does not belong to the user:\n`{\"message\": \"The course id is invalid\", \"errors\": {\"courseId\": [\"The course id is invalid\"]}}`.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/homework\/{schoolId}":{"post":{"tags":["Homework tasks"],"operationId":"createHomework","summary":"Create homework task","description":"Attaches a homework task to a lesson of the course `courseId`.\n`{schoolId}` is part of the path but is not checked; the course is taken from the body.\nThe `201` response is the homework task without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. Not validated; send the school of the course","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/CreateHomeworkRequest"}}}},"responses":{"201":{"description":"Created \u2014 the homework task is created","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/HomeworkTaskDetails"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.courseId` is returned when the course does not belong to the user,\nand `errors.lessonId` when the lesson is not a lesson of the course.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/homework\/{schoolId}\/{homeworkId}":{"put":{"tags":["Homework tasks"],"operationId":"updateHomework","summary":"Update homework task","description":"Replaces the homework task; omitted optional fields are cleared. The lesson of the task cannot be changed.\nThe response is the homework task without a `data` wrapper.\n","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The homework task must belong to a course of this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"homeworkId","in":"path","required":true,"description":"Homework task identifier. The homework task must belong to the user","schema":{"type":"integer","minimum":1},"example":7731}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/UpdateHomeworkRequest"}}}},"responses":{"200":{"description":"OK \u2014 the homework task is updated","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/HomeworkTaskDetails"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the homework task does not exist, is deleted, does not belong to the user or to a course of the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId` is not a number of up to 10 digits."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed (only the first error is returned)."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/homework\/{schoolId}\/{courseId}\/{homeworkId}":{"delete":{"tags":["Homework tasks"],"operationId":"deleteHomework","summary":"Delete homework task","parameters":[{"name":"schoolId","in":"path","required":true,"description":"School identifier. The course must belong to this school","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":3307},{"name":"courseId","in":"path","required":true,"description":"Course identifier. The course must belong to the school `{schoolId}`","schema":{"type":"integer","minimum":1,"maximum":9999999999},"example":12571},{"name":"homeworkId","in":"path","required":true,"description":"Homework task identifier. The homework task must belong to the user and to the course","schema":{"type":"integer","minimum":1},"example":7731}],"responses":{"204":{"description":"No Content \u2014 the homework task is deleted"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the homework task does not exist or does not belong to the user or to the course, or the course does not belong to the school `{schoolId}` (`ErrorList`), or a common access error (`ErrorResponse`)."},"404":{"$ref":"#\/components\/responses\/NotFound","description":"Not found \u2014 `schoolId`\/`courseId` is not a number of up to 10 digits."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/homeworks\/list\/checking":{"get":{"tags":["Homeworks"],"operationId":"listHomeworksForChecking","summary":"List student homeworks by review status","description":"Returns student homeworks with the given review status (`checking` by default), newest first,\nwith `offset`\/`limit` pagination. `meta.total` is the number of matches before pagination.\n","parameters":[{"name":"limit","in":"query","required":true,"description":"Maximum number of homeworks to return","schema":{"type":"integer","minimum":1,"maximum":1000},"example":50},{"name":"offset","in":"query","required":true,"description":"Number of homeworks to skip","schema":{"type":"integer","minimum":0},"example":0},{"name":"status","in":"query","required":false,"description":"Review status of the homework","schema":{"type":"string","enum":["checking","accepted","declined","autoAccepted","rework","acceptedWithoutAnswer","messageFromStudent","acceptWithRate"],"default":"checking"},"example":"checking"},{"name":"courseId","in":"query","required":false,"description":"Only homeworks of this course. The course must belong to the user and must not be blocked","schema":{"type":"integer"},"example":12571},{"name":"schoolId","in":"query","required":false,"description":"Only homeworks of courses of this school. The school must belong to the user","schema":{"type":"integer"},"example":3307}],"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/StudentHomeworkList"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"422":{"$ref":"#\/components\/responses\/ValidationFailed","description":"Validation failed. Besides field errors, `errors.courseId` is \"The course id is invalid\" and\n`errors.schoolId` is \"School does not belong to user\" when the course or school is not available to the user.\n"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/homeworks\/{studentHomeworkId}":{"get":{"tags":["Homeworks"],"operationId":"getStudentHomework","summary":"Get student homework","description":"The homework task and the student's latest answer to it.","parameters":[{"name":"studentHomeworkId","in":"path","required":true,"description":"Student homework identifier (`studentHomeworkId` from `listHomeworksForChecking`). The homework must belong to the user","schema":{"type":"integer","minimum":1},"example":2142}],"responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/StudentHomeworkResponse"}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the student homework does not exist or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/homeworks\/{studentHomeworkId}\/rate":{"post":{"tags":["Homeworks"],"operationId":"rateStudentHomework","summary":"Accept a student homework or send it for rework","description":"Sets the review status of the student homework and marks the student's messages as read.\nSending an accepted homework for rework makes its lesson not completed for the student again.\nIf `message` is set, it is sent to the student as a text message from the teacher.\n","parameters":[{"name":"studentHomeworkId","in":"path","required":true,"description":"Student homework identifier (`studentHomeworkId` from `listHomeworksForChecking`). The homework must belong to the user","schema":{"type":"integer","minimum":1},"example":2142}],"requestBody":{"required":true,"content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/RateStudentHomeworkRequest"}}}},"responses":{"204":{"description":"No Content \u2014 the homework is rated"},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the student homework does not exist or does not belong to the user (`ErrorList`), or a common access error (`ErrorResponse`)."},"422":{"$ref":"#\/components\/responses\/ValidationFailed"},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}},"\/tags":{"get":{"tags":["Tags"],"operationId":"listTags","summary":"Get list of tags","description":"Returns all active contact tags of the user from SendPulse CRM, without pagination.\nThe response is a plain array without a `data` wrapper.\nIf CRM rejects the request, its error code and message are returned as `ErrorResponse`.\n","responses":{"200":{"description":"OK","content":{"application\/json":{"schema":{"type":"array","items":{"$ref":"#\/components\/schemas\/Tag"}}}}},"401":{"$ref":"#\/components\/responses\/Unauthorized"},"403":{"$ref":"#\/components\/responses\/Forbidden","description":"Forbidden \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff (`ErrorResponse`)."},"429":{"$ref":"#\/components\/responses\/TooManyRequests"}}}}},"components":{"schemas":{"ErrorResponse":{"type":"object","description":"Error returned by authentication, rate limiting, tariff checks and explicit aborts","required":["success","error"],"properties":{"success":{"type":"boolean","enum":[false],"example":false},"error":{"type":"object","required":["code","message"],"properties":{"code":{"type":"integer","description":"Equals the HTTP status code","example":403},"message":{"type":"string","description":"Human-readable reason, may be empty","example":"Public API is not available for the current tariff"}}}}},"ErrorItem":{"type":"object","required":["code","message"],"properties":{"code":{"type":"integer","description":"Equals the HTTP status code","example":403},"message":{"type":"string","example":"Forbidden"}}},"ErrorList":{"type":"object","description":"Error returned when the requested entity does not belong to the user","required":["errors"],"properties":{"errors":{"type":"array","items":{"$ref":"#\/components\/schemas\/ErrorItem"}}}},"ValidationError":{"type":"object","required":["message","errors"],"properties":{"message":{"type":"string","description":"The first validation error, with the number of remaining errors","example":"The email field is required. (and 1 more error)"},"errors":{"type":"object","description":"Validation messages keyed by field name (nested fields use dot notation, e.g. `message.text`)","additionalProperties":{"type":"array","items":{"type":"string"}},"example":{"email":["The email field is required."],"language":["The language field is required."]}}}},"StudentAlreadyOnCourse":{"type":"object","required":["message","code","data"],"properties":{"message":{"type":"string","example":"Student already registered on course."},"code":{"type":"string","enum":["student_already_on_course"],"example":"student_already_on_course"},"data":{"$ref":"#\/components\/schemas\/Student"}}},"CourseList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/Course"}}}},"Course":{"type":"object","required":["id","schoolId","userId","status","domainId","landingId","pageId","name","slug","landingImage","coverImage","startDate","endDate","timezone","passingScore","isLinear","completionCriterion","createdAt","wasStarted","needRegeneration","redirectUrl","failedRedirectUrl","studentCount","isCourseHasCertifiedStudents","categoriesIds","isCertificate","hasPaidTariffs","groupId"],"properties":{"id":{"type":"integer","description":"Course identifier","example":12571},"schoolId":{"type":"integer","description":"School identifier","example":12224},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"status":{"type":"string","description":"Course status (blocked courses are not returned)","enum":["inProgress","inactive","planned"],"example":"inProgress"},"domainId":{"type":["integer","null"],"description":"Domain identifier","example":2201},"landingId":{"type":["integer","null"],"description":"Landing identifier","example":88412},"pageId":{"type":["integer","null"],"description":"Page identifier","example":190334},"name":{"type":"string","description":"Course name","example":"Python for beginners"},"slug":{"type":["string","null"],"description":"URL-friendly course identifier","example":"python-basics"},"landingImage":{"type":["string","null"],"description":"Main course image URL","example":"https:\/\/cdn.example.com\/edu\/courses\/12571\/landing.png"},"coverImage":{"type":["string","null"],"description":"Cover image URL","example":"https:\/\/cdn.example.com\/edu\/courses\/12571\/cover.png"},"startDate":{"type":["string","null"],"format":"date-time","description":"Course start date, UTC","example":"2026-01-15T09:00:00.000000Z"},"endDate":{"type":["string","null"],"format":"date-time","description":"Course end date, UTC","example":"2026-12-31T21:59:59.000000Z"},"timezone":{"type":["string","null"],"description":"Timezone of the course dates","example":"Europe\/Kyiv"},"passingScore":{"type":["integer","null"],"description":"Minimum test score to pass the course","example":70},"isLinear":{"type":"boolean","description":"Lessons must be completed in order","example":false},"completionCriterion":{"type":"string","description":"What the student must do to complete the course","enum":["none","lessonsCompleted","testPassed","lessonsCompletedTestPassed","withoutEnding"],"example":"lessonsCompleted"},"createdAt":{"type":["string","null"],"format":"date-time","description":"Creation time, UTC","example":"2025-11-03T12:40:11.000000Z"},"wasStarted":{"type":"boolean","description":"The course has been started at least once","example":true},"needRegeneration":{"type":"boolean","description":"The course page needs regeneration","example":false},"redirectUrl":{"type":["string","null"],"description":"Redirect URL after successful completion","example":"https:\/\/example.com\/thank-you"},"failedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after failed completion","example":"https:\/\/example.com\/try-again"},"studentCount":{"type":["integer","null"],"description":"Number of active students on the course, `null` for a just created or updated course","example":42},"isCourseHasCertifiedStudents":{"type":"boolean","description":"At least one student has the `certificated` status","example":true},"categoriesIds":{"type":"array","description":"IDs of attached categories","items":{"type":"integer"},"example":[14,27]},"isCertificate":{"type":"boolean","description":"The course issues a certificate","example":true},"hasPaidTariffs":{"type":"boolean","description":"The course has an active tariff with a payment method","example":true},"groupId":{"type":["integer","null"],"description":"Course group identifier","example":610},"sectionsWithLessons":{"type":"array","description":"Course structure; filled only when course data is built for landing generation, in this API always an empty array","items":{"$ref":"#\/components\/schemas\/CourseStructureSection"}},"userTariffStatus":{"type":["string","null"],"enum":["blocked","active","pending",null],"description":"Status of the course owner's user tariff; filled only for landing generation, in this API always `null`","example":"active"},"promoCodeExists":{"type":"boolean","description":"The course has at least one active promo code","example":false}}},"CourseTariff":{"type":"object","required":["id","courseId","name","isMain","isPaid","succeedRedirectUrl","failedRedirectUrl","status","order","countOfStudents","accessRestrictionSettingsVO","paymentMethodsCollection","studentBaseStateSettingDTO","contentAccesses","functionalityAccesses","courseTariffSettingDTO","wasStarted","costCalculationPolicies","tariffRenewals","advertisingText","pricingType"],"properties":{"id":{"type":"integer","description":"Tariff identifier","example":3301},"courseId":{"type":"integer","description":"Course identifier","example":12571},"name":{"type":"string","description":"Tariff name","example":"Premium"},"isMain":{"type":"boolean","description":"The default tariff of the course","example":true},"isPaid":{"type":"boolean","description":"The tariff has at least one payment method","example":true},"succeedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after successful payment","example":"https:\/\/example.com\/payment-success"},"failedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after failed payment","example":"https:\/\/example.com\/payment-failed"},"status":{"type":"string","description":"Tariff status","enum":["active","inactive"],"example":"active"},"order":{"type":["integer","null"],"description":"Display order","example":1},"countOfStudents":{"type":["integer","null"],"minimum":1,"description":"Number of students on the tariff. `null` when there are no students (never `0`)","example":48},"accessRestrictionSettingsVO":{"description":"Course access restriction of the tariff, `null` if not configured.\nAn empty array `[]` (not an object) is returned when the settings exist but no restriction is set\n","oneOf":[{"$ref":"#\/components\/schemas\/CourseAccessRestriction"},{"type":"array","maxItems":0},{"type":"null"}]},"paymentMethodsCollection":{"type":"array","items":{"$ref":"#\/components\/schemas\/PaymentMethod"}},"studentBaseStateSettingDTO":{"description":"Initial state applied to a student enrolled on the tariff, `null` if not configured","oneOf":[{"$ref":"#\/components\/schemas\/StudentBaseStateSetting"},{"type":"null"}]},"contentAccesses":{"type":"array","description":"Course content available on the tariff","items":{"$ref":"#\/components\/schemas\/ContentAccess"}},"functionalityAccesses":{"type":"array","description":"Functionality available on the tariff","items":{"$ref":"#\/components\/schemas\/FunctionalityAccess"}},"courseTariffSettingDTO":{"description":"Tariff settings, `null` if not configured","oneOf":[{"$ref":"#\/components\/schemas\/CourseTariffSetting"},{"type":"null"}]},"wasStarted":{"type":"boolean","description":"The tariff has been started at least once","example":true},"costCalculationPolicies":{"type":"array","description":"Upgrade price rules from this tariff to other tariffs","items":{"$ref":"#\/components\/schemas\/CostCalculationPolicy"}},"tariffRenewals":{"type":"array","items":{"$ref":"#\/components\/schemas\/TariffRenewal"}},"products":{"type":["array","null"],"description":"Products linked to the tariff","items":{"type":"object","required":["id","courseTariffId","productId"],"properties":{"id":{"type":"integer","example":215},"courseTariffId":{"type":"integer","description":"Tariff identifier","example":4521},"productId":{"type":"integer","description":"Product identifier","example":77}}}},"advertisingText":{"description":"Advertising text of the tariff, `null` if not set","oneOf":[{"$ref":"#\/components\/schemas\/CourseTariffAdvertisingText"},{"type":"null"}]},"pricingType":{"type":["integer","null"],"enum":[1,2,3,null],"description":"Pricing type of the tariff: `1` \u2014 free, `2` \u2014 one-time payment, `3` \u2014 subscription","example":3}}},"CourseAccessRestriction":{"type":"object","description":"Only the restriction that is set is present","properties":{"restrictedDays":{"type":"integer","minimum":1,"description":"Access is limited to this number of days after enrollment","example":90},"restrictedToDate":{"type":"string","format":"date-time","description":"Access is limited until this moment, UTC. Present together with `timezone`","example":"2026-12-31T21:59:59.000000Z"},"timezone":{"type":["string","null"],"description":"Timezone in which `restrictedToDate` was set. Present together with `restrictedToDate`","example":"Europe\/Kyiv"}}},"PaymentMethod":{"type":"object","required":["id","userId","courseId","courseTariffId","name","price","currency","paymentId","paymentType","rro","paymentDescription","products","recurringMode"],"properties":{"id":{"type":"integer","description":"Payment method identifier","example":3920},"userId":{"type":"integer","description":"Owner user identifier","example":8945612},"courseId":{"type":"integer","description":"Course identifier","example":12571},"courseTariffId":{"type":"integer","description":"Tariff identifier","example":4521},"name":{"type":"string","description":"Payment method name","example":"Card payment"},"price":{"type":"number","description":"Price","example":1500},"currency":{"type":"string","description":"Currency code","example":"UAH"},"paymentId":{"type":"string","description":"Payment method key used in payment links","example":"1c9f4e2a-5b7d-4f0e-9a51-2d6c1e8b7f30"},"paymentType":{"type":"string","description":"Payment provider","enum":["YooMoney","PayPal","Fondy","YooKassa","ROBOKASSA","Stripe","MERCADOPAGO","LiqPay","Wayforpay","Flutterwave","Monobank","Cryptomus","Whitepay","TELEGRAM","Klarna","StripeConnect","RozetkaPay","Novapay"],"example":"Stripe"},"rro":{"type":["string","null"],"description":"Product code for the fiscal receipt (used by Monobank and LiqPay)","example":null},"paymentDescription":{"type":["string","null"],"description":"Payment description","example":"Payment for the Python for beginners course"},"products":{"type":"array","description":"Products linked to the tariff of this payment method (the same list for every payment method of the tariff)","items":{"$ref":"#\/components\/schemas\/CourseTariffProduct"}},"recurringMode":{"type":["string","null"],"enum":["daily","weekly","monthly","quarterly","halfyearly","yearly",null],"description":"Billing period of a subscription, `null` for a one-time payment method","example":"monthly"}}},"CourseTariffProduct":{"type":"object","description":"Raw database record, fields are in snake_case","required":["id","course_tariff_id","product_id","created_at","updated_at"],"properties":{"id":{"type":"integer","example":215},"course_tariff_id":{"type":"integer","description":"Tariff identifier","example":4521},"product_id":{"type":"integer","description":"Product identifier","example":3301},"created_at":{"type":["string","null"],"format":"date-time","example":"2026-09-01T08:00:00.000000Z"},"updated_at":{"type":["string","null"],"format":"date-time","example":"2026-09-01T08:00:00.000000Z"}}},"StudentBaseStateSetting":{"type":"object","required":["id","courseTariffId","groupId","responsibleId","tagIds","dealCreation"],"properties":{"id":{"type":"integer","description":"Setting identifier","example":1187},"courseTariffId":{"type":"integer","description":"Tariff identifier","example":4521},"groupId":{"type":["integer","null"],"description":"Student group the student is added to","example":3145},"responsibleId":{"type":["integer","null"],"description":"Responsible user assigned to the student","example":8945613},"tagIds":{"type":["array","null"],"description":"Tags assigned to the student","items":{"type":"integer"},"example":[50213]},"dealCreation":{"description":"CRM deal created for the student, `null` if disabled","oneOf":[{"$ref":"#\/components\/schemas\/DealCreation"},{"type":"null"}]}}},"DealCreation":{"type":"object","required":["pipelineId","stepId","dealName","createDealOnPayment"],"properties":{"pipelineId":{"type":"integer","description":"CRM pipeline identifier","example":4410},"stepId":{"type":"integer","description":"CRM pipeline step identifier","example":17702},"dealName":{"type":"string","description":"Deal name","example":"Python for beginners \u2014 Premium"},"createDealOnPayment":{"type":"boolean","description":"Create the deal only after payment","example":true}}},"ContentAccess":{"type":"object","required":["courseTariffId","contentType","entityId"],"properties":{"courseTariffId":{"type":"integer","description":"Tariff identifier","example":4521},"contentType":{"type":"string","description":"Type of the course entity","enum":["section","lesson","test","certificate","form"],"example":"lesson"},"entityId":{"type":"integer","description":"Identifier of the course entity","example":90211}}},"FunctionalityAccess":{"type":"object","required":["courseTariffId","type"],"properties":{"courseTariffId":{"type":"integer","description":"Tariff identifier","example":4521},"type":{"type":"string","description":"Functionality available to students","enum":["chat","audioMessage","stateVideo","homeworkDiscussion"],"example":"chat"}}},"CourseTariffSetting":{"type":"object","required":["courseTariffId","startDate","endDate","timezone","contentShow","quota"],"properties":{"courseTariffId":{"type":"integer","description":"Tariff identifier","example":4521},"startDate":{"type":["string","null"],"format":"date-time","description":"Tariff availability start, UTC","example":"2026-09-01T06:00:00.000000Z"},"endDate":{"type":["string","null"],"format":"date-time","description":"Tariff availability end, UTC","example":"2026-12-31T21:59:59.000000Z"},"timezone":{"type":["string","null"],"description":"Timezone of the dates","example":"Europe\/Kyiv"},"contentShow":{"type":"boolean","description":"Show content unavailable on the tariff to students","example":true},"quota":{"type":["integer","null"],"description":"Maximum number of students on the tariff, `null` for unlimited","example":100}}},"CostCalculationPolicy":{"type":"object","required":["type","courseTariffFrom","courseTariffTo","status","state"],"properties":{"type":{"type":"integer","description":"Price calculation: `1` \u2014 automatically, `2` \u2014 manual","enum":[1,2],"example":2},"courseTariffFrom":{"type":"integer","description":"Source tariff identifier","example":4520},"courseTariffTo":{"type":"integer","description":"Target tariff identifier","example":4521},"status":{"type":"integer","description":"`1` \u2014 inactive, `2` \u2014 active","enum":[1,2],"example":2},"state":{"type":["number","null"],"description":"Manual upgrade price","example":49.99}}},"TariffRenewal":{"type":"object","required":["id","courseTariffId","name","status","days","amount","succeedRedirectUrl","failedRedirectUrl","dealCreation"],"properties":{"id":{"type":"integer","description":"Renewal identifier","example":702},"courseTariffId":{"type":"integer","description":"Tariff identifier","example":4521},"name":{"type":"string","description":"Renewal name","example":"Extend for 30 days"},"status":{"type":"string","enum":["active","inactive"],"example":"active"},"days":{"type":"integer","description":"Number of days the access is extended by","example":30},"amount":{"type":["number","null"],"description":"Renewal price","example":19.99},"succeedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after successful payment","example":"https:\/\/example.com\/renewal-success"},"failedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after failed payment","example":"https:\/\/example.com\/renewal-failed"},"dealCreation":{"description":"CRM deal created on renewal, `null` if disabled","oneOf":[{"$ref":"#\/components\/schemas\/DealCreation"},{"type":"null"}]}}},"CourseTariffAdvertisingText":{"type":"object","required":["courseTariffId","text"],"properties":{"courseTariffId":{"type":"integer","description":"Tariff identifier","example":4521},"text":{"type":"string","description":"Advertising text","example":"Personal mentor and weekly Q&A sessions"}}},"School":{"type":"object","required":["id","userId","domainId","landingId","pageId","name","studentsName","isLms","status","order","iconUrl","groups"],"properties":{"id":{"type":"integer","description":"School identifier","example":12224},"userId":{"type":"integer","description":"School owner (user) identifier","example":8812345},"domainId":{"type":"integer","description":"Domain identifier of the school","example":2201},"landingId":{"type":["integer","null"],"description":"Landing identifier","example":88400},"pageId":{"type":["integer","null"],"description":"Page identifier","example":190300},"name":{"type":"string","description":"School name","example":"Coding school"},"studentsName":{"type":["string","null"],"description":"Custom name for students (e.g. pupils, audience)","example":"Pupils"},"isLms":{"type":"boolean","description":"The school is an LMS school","example":false},"status":{"type":"string","description":"School status","enum":["inactive","active","deleted"],"example":"active"},"order":{"type":["integer","null"],"description":"Display order in lists","example":1},"iconUrl":{"type":["string","null"],"description":"School icon URL from the student cabinet settings","example":"https:\/\/cdn.example.com\/edu\/schools\/3307\/icon.png"},"coursesCount":{"type":["integer","null"],"description":"Number of courses of the school","example":5},"gamificationEnabled":{"type":"boolean","description":"Gamification is enabled for the school","example":false},"groups":{"type":"array","description":"Course groups of the school","items":{"$ref":"#\/components\/schemas\/CourseGroup"}}}},"CourseGroup":{"type":"object","required":["id","name","schoolId"],"properties":{"id":{"type":"integer","description":"Course group identifier","example":610},"name":{"type":"string","description":"Course group name","example":"Programming"},"schoolId":{"type":"integer","description":"School identifier","example":3307}}},"StudentGroup":{"type":"object","required":["id","userId","responsibleId","courseId","name","color"],"properties":{"id":{"type":"integer","description":"Group identifier","example":3145},"userId":{"type":"integer","description":"Identifier of the account owner","example":8945612},"responsibleId":{"type":["integer","null"],"description":"Identifier of the user responsible for the group, `null` if not assigned","example":8945613},"courseId":{"type":"integer","description":"Identifier of the course the group belongs to","example":12571},"name":{"type":"string","maxLength":255,"description":"Group name","example":"Spring stream"},"color":{"type":"string","pattern":"^#([a-fA-F0-9]{6}|[a-fA-F0-9]{3})$","description":"Group color as a hex code","example":"#4a90e2"}}},"Tag":{"type":"object","required":["id","name","colorBackground","colorText","contactCount","taskCount"],"properties":{"id":{"type":"integer","description":"Tag identifier","example":50213},"name":{"type":"string","maxLength":64,"description":"Tag name, unique among the user's active tags","example":"VIP"},"colorBackground":{"type":["string","null"],"description":"Background color of the tag, `null` if not set","example":"#ffe8b3"},"colorText":{"type":"string","description":"Text color of the tag","example":"#688FA1"},"contactCount":{"type":"integer","minimum":0,"description":"Number of CRM contacts with this tag","example":128},"taskCount":{"type":"integer","minimum":0,"description":"Number of CRM tasks with this tag","example":4}}},"CreateStudentRequest":{"type":"object","required":["courseId","email","language"],"description":"Either `firstName` or `lastName` must be set.","properties":{"courseId":{"type":"integer","description":"Identifier of the course to enroll the student on. Must be a JSON integer, a numeric string is rejected","example":12571},"email":{"type":"string","format":"email","description":"Student email. An existing active student with this email in the school is reused","example":"student@example.com"},"firstName":{"type":["string","null"],"maxLength":128,"description":"Student first name. Required if `lastName` is empty. A new student without a first name gets the part of the email before `@`","example":"Olena"},"lastName":{"type":["string","null"],"maxLength":128,"description":"Student last name","example":"Kovalenko"},"language":{"type":"string","pattern":"^[a-z]{2}_[A-Z]{2}$","description":"Language of a new student","example":"uk_UA"},"courseTariffId":{"type":["integer","null"],"description":"Tariff of the course to put the student on. The tariff must belong to the course and be active.\nIf omitted, the student is enrolled without a tariff\n","example":4521},"markPaid":{"type":"boolean","default":false,"description":"Mark the student's tariff as paid. Applied only together with `courseTariffId`","example":true},"productId":{"type":["integer","null"],"description":"Identifier of the product the student paid through. Only recorded in the course history; does not mark the tariff as paid","example":3301},"tagIds":{"type":["array","null"],"description":"Contact tag identifiers (see `listTags`) to add to the student. Tags of the selected tariff are added as well;\nexisting tags are never removed\n","items":{"type":"integer"},"example":[50213,50214]},"marketingOptIn":{"type":["boolean","null"],"description":"Consent to marketing emails, applied only when a new student is created.\nOmitted or `null` means no consent. Without consent the student gets only the email with login credentials\n","example":true},"messenger":{"type":"array","description":"Messenger contact of the student","items":{"$ref":"#\/components\/schemas\/StudentMessenger"}}}},"StudentCourseStatisticsResponse":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#\/components\/schemas\/StudentCourseStatistics"}}},"StudentCourseStatistics":{"type":"object","required":["schools","groups","responsible"],"properties":{"schools":{"type":"array","description":"Schools with the student's courses","items":{"$ref":"#\/components\/schemas\/StatisticsSchool"}},"groups":{"type":"array","description":"Groups of the student","items":{"$ref":"#\/components\/schemas\/StudentCourseGroup"}},"responsible":{"type":"array","description":"Users personally responsible for the student","items":{"$ref":"#\/components\/schemas\/StudentResponsible"}}}},"StudentCourseGroup":{"type":"object","required":["courseId","groupName","groupColor","responsibleUserId"],"properties":{"courseId":{"type":"integer","description":"Course of the group","example":12571},"groupName":{"type":"string","description":"Group name","example":"Spring stream"},"groupColor":{"type":["string","null"],"description":"Group color as a hex code","example":"#4a90e2"},"responsibleUserId":{"type":["integer","null"],"description":"User responsible for the group, `null` if not assigned","example":8945613}}},"StatisticsSchool":{"type":"object","required":["schoolName","isLms","schoolId","courses","externalContactId","marketingOptIn"],"properties":{"schoolName":{"type":"string","description":"School name","example":"Coding School"},"isLms":{"type":"boolean","description":"Whether the school works in LMS mode","example":false},"schoolId":{"type":"integer","description":"School identifier","example":3307},"courses":{"type":"array","description":"Courses of the student in the school","items":{"$ref":"#\/components\/schemas\/StatisticsCourse"}},"externalContactId":{"type":"string","format":"uuid","description":"Student UUID, used as the contact identifier in SendPulse CRM","example":"0b9f3c1e-5d4a-4e7b-9a61-2f8c7d3e1a90"},"marketingOptIn":{"type":["boolean","null"],"description":"Marketing consent of the student, `null` if the student never answered","example":true}}},"StatisticsCourse":{"type":"object","required":["id","status","name","statusStudentOnCourse","studentDateRegistrationOnCourse","studentEmail","studentLastEntry","courseAvailableDate","studentMetadata","landingUrl","feedback","sections","tests","homeworks","hideOrder","promoCode","promoCodeDiscount","studentTariff","gamificationData","subscriptionStatus"],"properties":{"id":{"type":"integer","description":"Course identifier","example":12571},"status":{"type":"string","enum":["inProgress","inactive","planned"],"description":"Course status","example":"inProgress"},"name":{"type":"string","description":"Course name","example":"Python for beginners"},"statusStudentOnCourse":{"type":"string","enum":["registered","inProgress","success","failed","certificated","deletedFromCourse"],"description":"Status of the student on the course","example":"inProgress"},"studentDateRegistrationOnCourse":{"type":["string","null"],"format":"date-time","description":"Date the student was added to the course, UTC","example":"2026-09-01T08:15:00.000000Z"},"studentEmail":{"type":"string","description":"Student email","example":"student@example.com"},"studentLastEntry":{"type":["string","null"],"format":"date-time","description":"Date of the student's last login, UTC; `null` if they never logged in","example":"2026-10-08T17:42:10.000000Z"},"courseAvailableDate":{"type":["string","null"],"format":"date-time","description":"End of the student's access to the course, UTC; `null` for unlimited access","example":"2026-12-31T21:59:59.000000Z"},"studentMetadata":{"type":["array","null"],"description":"Latest login sessions of the student, newest first. `null` when the user's tariff is free","items":{"$ref":"#\/components\/schemas\/StudentMetadata"}},"landingUrl":{"type":"string","description":"Course landing page URL","example":"https:\/\/school.example.com\/python-for-beginners"},"feedback":{"oneOf":[{"$ref":"#\/components\/schemas\/StudentFeedback"},{"type":"null"}],"description":"Student's feedback on the course, `null` if not left"},"sections":{"type":"array","description":"Course sections with lessons, forms and certificates available to the student","items":{"$ref":"#\/components\/schemas\/StatisticsSection"}},"tests":{"type":"array","description":"Course tests available to the student","items":{"$ref":"#\/components\/schemas\/StatisticsTest"}},"homeworks":{"type":"array","description":"Homeworks of the course lessons","items":{"$ref":"#\/components\/schemas\/StatisticsHomework"}},"hideOrder":{"type":"boolean","description":"Whether the order numbers of sections and lessons are hidden from students","example":false},"promoCode":{"type":["string","null"],"description":"Promo code used in the student's payment for the course","example":"AUTUMN10"},"promoCodeDiscount":{"oneOf":[{"$ref":"#\/components\/schemas\/PromoCodeDiscount"},{"type":"null"}],"description":"Discount of `promoCode`, `null` when there is no successful payment"},"studentTariff":{"oneOf":[{"$ref":"#\/components\/schemas\/StudentTariff"},{"type":"null"}],"description":"Tariff of the student on the course, `null` if the student has no tariff"},"gamificationData":{"oneOf":[{"$ref":"#\/components\/schemas\/GamificationData"},{"type":"null"}],"description":"Gamification progress, `null` when gamification is disabled for the school"},"subscriptionStatus":{"type":["integer","null"],"enum":[1,2,null],"description":"Subscription status of the student on the course: `1` \u2014 active (access end date is in the future),\n`2` \u2014 stopped; `null` when the student's tariff is not a subscription\n","example":1}}},"StudentMetadata":{"type":"object","required":["ip","countryCode","country","platformFamily","platformVersion","appVersion","browserFamily","createdAt"],"properties":{"ip":{"type":["string","null"],"description":"IP address","example":"203.0.113.42"},"countryCode":{"type":["string","null"],"description":"Country code","example":"UA"},"country":{"type":["string","null"],"description":"Country name","example":"Ukraine"},"platformFamily":{"type":["string","null"],"description":"Operating system family, lowercase","example":"android"},"platformVersion":{"type":["string","null"],"description":"Operating system version","example":"14"},"appVersion":{"type":["string","null"],"description":"Mobile app version, `null` for the web","example":"2.18.0"},"browserFamily":{"type":["string","null"],"description":"Browser family","example":"Chrome"},"createdAt":{"type":["string","null"],"format":"date-time","description":"Session date, UTC","example":"2026-10-08T17:42:10.000000Z"}}},"StudentFeedback":{"type":"object","required":["rate","message","date"],"properties":{"rate":{"type":["integer","null"],"description":"Rating given by the student","example":5},"message":{"type":["string","null"],"description":"Feedback text","example":"Great course, thanks!"},"date":{"type":"string","format":"date-time","description":"Date the feedback was left or last changed, UTC","example":"2026-10-01T12:00:00.000000Z"}}},"GamificationData":{"type":"object","required":["score","rating","ratingSize"],"properties":{"score":{"type":"integer","description":"Points of the student on the course","example":120},"rating":{"type":"integer","description":"Position of the student in the course rating, starting from 1","example":3},"ratingSize":{"type":"integer","description":"Number of students in the course rating","example":48}}},"StatisticsSection":{"type":"object","required":["id","name","order","status","lessons","certificateSections","forms"],"properties":{"id":{"type":"integer","description":"Section identifier","example":4410},"name":{"type":"string","description":"Section name","example":"Basics"},"order":{"type":"integer","description":"Position of the section in the course","example":1},"status":{"type":"string","enum":["closed","opened","planned","hidden"],"description":"Section status","example":"opened"},"lessons":{"type":"array","items":{"$ref":"#\/components\/schemas\/StatisticsLesson"}},"certificateSections":{"type":"array","items":{"$ref":"#\/components\/schemas\/StatisticsCertificateSection"}},"forms":{"type":"array","items":{"$ref":"#\/components\/schemas\/StatisticsForm"}}}},"StatisticsLesson":{"type":"object","required":["id","name","order","statusStudentOnLesson","feedback","status"],"properties":{"id":{"type":"integer","description":"Lesson identifier","example":90211},"name":{"type":"string","description":"Lesson name","example":"Variables and types"},"order":{"type":"integer","description":"Position of the lesson in the section","example":1},"statusStudentOnLesson":{"oneOf":[{"$ref":"#\/components\/schemas\/LessonProgress"},{"type":"null"}],"description":"Progress of the student on the lesson, `null` if the lesson was never opened"},"feedback":{"oneOf":[{"$ref":"#\/components\/schemas\/StudentFeedback"},{"type":"null"}],"description":"Student's feedback on the lesson, `null` if not left"},"status":{"type":"string","enum":["closed","opened","planned","hidden"],"description":"Lesson status","example":"opened"}}},"LessonProgress":{"type":"object","required":["status","updatedAt"],"properties":{"status":{"type":"string","enum":["doNotStarted","started","completed"],"description":"Status of the student on the lesson","example":"completed"},"updatedAt":{"type":"string","format":"date-time","description":"Date of the last status change, UTC","example":"2026-09-03T10:20:00.000000Z"}}},"StatisticsCertificateSection":{"type":"object","required":["id","name","sectionId","order","dateReceived","status","haveCertificate","isImported","certificateId"],"properties":{"id":{"type":"integer","description":"Certificate section identifier","example":18},"name":{"type":"string","description":"Certificate name","example":"Python basics certificate"},"sectionId":{"type":"integer","description":"Course section the certificate belongs to","example":4410},"order":{"type":"integer","description":"Position in the section","example":5},"dateReceived":{"type":["string","null"],"format":"date-time","description":"Date the student received the certificate, UTC; `null` if not received","example":"2026-09-20T09:00:00.000000Z"},"status":{"type":"string","enum":["inactive","active","planned","hidden"],"description":"Certificate section status","example":"active"},"haveCertificate":{"type":"boolean","description":"Whether a certificate template is set","example":true},"isImported":{"type":"boolean","description":"Whether the certificate was imported","example":false},"certificateId":{"type":["integer","null"],"description":"Identifier of the student's certificate, `null` if not received","example":66120}}},"StatisticsForm":{"type":"object","required":["id","name","order","status","sectionId","questionsCount","answeredQuestionsCount","studentStatus"],"properties":{"id":{"type":"integer","description":"Form identifier","example":330},"name":{"type":"string","description":"Form name","example":"Entry survey"},"order":{"type":"integer","description":"Position in the section","example":2},"status":{"type":"string","enum":["inactive","active","planned","hidden"],"description":"Form status","example":"active"},"sectionId":{"type":"integer","description":"Course section the form belongs to","example":4410},"questionsCount":{"type":"integer","description":"Number of questions","example":6},"answeredQuestionsCount":{"type":"integer","description":"Number of questions answered by the student","example":6},"studentStatus":{"type":["string","null"],"enum":["started","completed",null],"description":"Status of the student on the form, `null` if not started","example":"completed"}}},"StatisticsTest":{"type":"object","required":["id","name","studentStatus","score","relatedEntityType","relatedEntityId","order","feedback","status"],"properties":{"id":{"type":"integer","description":"Test identifier","example":5120},"name":{"type":"string","description":"Test name","example":"Final test"},"studentStatus":{"type":["string","null"],"enum":["blocked","running","finished","failed",null],"description":"Status of the student on the test, `null` if not started","example":"finished"},"score":{"$ref":"#\/components\/schemas\/TestScore"},"relatedEntityType":{"type":"string","enum":["course","section","lesson"],"description":"Entity the test is attached to","example":"lesson"},"relatedEntityId":{"type":["integer","null"],"description":"Identifier of the entity the test is attached to","example":90211},"order":{"type":"integer","description":"Position of the test","example":3},"feedback":{"oneOf":[{"$ref":"#\/components\/schemas\/StudentFeedback"},{"type":"null"}],"description":"Student's feedback on the test, `null` if not left"},"status":{"type":"string","enum":["active","inactive","planned","hidden"],"description":"Test status","example":"active"},"timeLimit":{"type":["integer","null"],"description":"Time limit for passing the test, in seconds; `null` if the test has no time limit","example":1800},"spentTime":{"type":["integer","null"],"description":"Time spent on the latest attempt, in seconds (capped at `timeLimit`); `null` if the test has no time\nlimit (time is tracked only for time-limited tests) or the student has not started the test;\n`0` if the attempt was started before time tracking was introduced\n","example":1240}}},"TestScore":{"type":"object","required":["userScore","minScore","maxScore"],"properties":{"userScore":{"type":"integer","description":"Best score of the student, `0` if not passed","example":8},"minScore":{"type":"integer","description":"Minimum score to pass the test","example":6},"maxScore":{"type":"integer","description":"Maximum score of the test","example":10}}},"StatisticsHomework":{"type":"object","required":["lessonId","name","status","rate","maxRate"],"properties":{"lessonId":{"type":"integer","description":"Lesson the homework belongs to","example":90211},"name":{"type":"string","description":"Homework name","example":"Write a calculator"},"status":{"type":["string","null"],"enum":["checking","accepted","declined","autoAccepted","rework","acceptedWithoutAnswer","messageFromStudent","acceptWithRate",null],"description":"Status of the student's latest answer, `null` if the student has not answered","example":"accepted"},"rate":{"type":["integer","null"],"description":"Rate given for the homework","example":9},"maxRate":{"type":["integer","null"],"description":"Maximum rate of the homework","example":10}}},"ChangeStudentCourseStatusRequest":{"type":"object","required":["studentId","status"],"properties":{"studentId":{"type":"integer","description":"Identifier of a student on the course. Must be a JSON integer; the student must not be blocked or deleted","example":7712345},"status":{"type":"string","enum":["registered","inProgress","success","certificated"],"description":"Completion status to set","example":"success"}}},"ChangeStudentCourseProgressRequest":{"type":"object","required":["studentId"],"properties":{"studentId":{"type":"integer","description":"Identifier of a student on the course","example":7712345},"passed":{"oneOf":[{"$ref":"#\/components\/schemas\/CourseProgressItems"},{"type":"null"}],"description":"Lessons and tests to mark as passed"},"notPassed":{"oneOf":[{"$ref":"#\/components\/schemas\/CourseProgressItems"},{"type":"null"}],"description":"Lessons and tests to reset to not passed"}}},"CourseProgressItems":{"type":"object","properties":{"lessons":{"type":"array","description":"Identifiers of lessons of the course","items":{"type":"integer"},"example":[90211,90212]},"tests":{"type":"array","description":"Identifiers of tests of the course","items":{"type":"integer"},"example":[5120]}}},"StudentHomeworkList":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/StudentHomeworkListItem"}},"meta":{"type":"object","required":["total"],"properties":{"total":{"type":"integer","description":"Number of matches before pagination","example":3}}}}},"StudentHomeworkListItem":{"type":"object","required":["studentHomeworkId","schoolId","courseId","homeworkId","lessonId","lessonName","studentId","studentName"],"properties":{"studentHomeworkId":{"type":"integer","description":"Student homework identifier, used in `getStudentHomework` and `rateStudentHomework`","example":2142},"schoolId":{"type":"integer","description":"School identifier","example":3307},"courseId":{"type":"integer","description":"Course identifier","example":12571},"homeworkId":{"type":"integer","description":"Homework task identifier","example":501},"lessonId":{"type":"integer","description":"Lesson the homework belongs to","example":90211},"lessonName":{"type":"string","description":"Lesson name","example":"Variables and types"},"studentId":{"type":"integer","description":"Student identifier","example":7712345},"studentName":{"type":"string","description":"First and last name of the student separated by a space","example":"Olena Kovalenko"}}},"StudentHomeworkResponse":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#\/components\/schemas\/StudentHomework"}}},"StudentHomework":{"type":"object","required":["homework","answer"],"properties":{"homework":{"$ref":"#\/components\/schemas\/HomeworkTask"},"answer":{"$ref":"#\/components\/schemas\/HomeworkAnswer"}}},"HomeworkTask":{"type":"object","required":["id","name","lessonId","content","filesPaths"],"properties":{"id":{"type":"integer","description":"Homework task identifier","example":501},"name":{"type":"string","description":"Homework name","example":"Write a calculator"},"lessonId":{"type":"integer","description":"Lesson the homework belongs to","example":90211},"content":{"type":"string","description":"Homework task as plain text, without formatting; may be an empty string","example":"Write a script that adds two numbers entered by the user."},"filesPaths":{"type":["array","null"],"description":"Paths of files attached to the task in the user's file storage, `null` if there are none","items":{"type":"string"},"example":["\/edu\/homeworks\/501\/task.pdf"]}}},"HomeworkAnswer":{"type":"object","required":["message","filesPaths"],"properties":{"message":{"type":["string","null"],"description":"Text of the student's latest answer, `null` if the answer has only files","example":"Here is my solution, please check it."},"filesPaths":{"type":"array","description":"URLs of files attached to the answer","items":{"type":"string","format":"uri"},"example":["https:\/\/cdn.example.com\/a1b2c3\/edu\/answers\/2142\/solution.zip"]}}},"RateStudentHomeworkRequest":{"type":"object","required":["status"],"properties":{"status":{"type":"string","enum":["accepted","rework"],"description":"`accepted` \u2014 accept the homework, `rework` \u2014 send it back to the student for rework","example":"accepted"},"message":{"oneOf":[{"$ref":"#\/components\/schemas\/HomeworkTeacherMessage"},{"type":"null"}],"description":"Message to the student"}}},"HomeworkTeacherMessage":{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":5000,"description":"Message text","example":"Good job, well done!"}}},"SearchAuditoryRequest":{"type":"object","description":"`offset` and `limit` are required unless `exportStudentIds` is set.","properties":{"offset":{"type":"integer","minimum":0,"description":"Number of matches to skip","example":0},"limit":{"type":"integer","minimum":0,"description":"Maximum number of students to return","example":20},"exportStudentIds":{"type":["array","null"],"description":"Return only students with these identifiers. Each item must be a JSON integer.\nWith this field `offset` and `limit` are optional; without them all listed students are returned\n","items":{"type":"integer"},"example":[7712345,7712346]},"courseIds":{"type":["array","null"],"description":"Only students on any of these courses. `-1` matches students who are not on any course","items":{"type":"integer"},"example":[12571,-1]},"courseStatus":{"type":"array","description":"Statuses of the student on a course","items":{"type":"string","enum":["registered","inProgress","success","failed","certificated","deletedFromCourse"]},"example":["inProgress","success"]},"firstName":{"type":"string","description":"Substring of the first name","example":"Ole"},"lastName":{"type":"string","description":"Substring of the last name","example":"Kova"},"email":{"type":"string","description":"Substring of the email","example":"@example.com"},"tags":{"type":"array","description":"Contact tag identifiers (see `listTags`)","items":{"type":"integer"},"example":[50213,50214]},"tagsCondition":{"type":["string","null"],"enum":["all","any",null],"default":"any","description":"`any` \u2014 the student has at least one of `tags`, `all` \u2014 the student has every tag","example":"any"},"isPaid":{"type":"boolean","description":"`true` \u2014 the student's tariff on a course is paid; `false` \u2014 not paid or no tariff","example":true},"marketingOptIn":{"type":["boolean","null"],"description":"Marketing consent of the student. Students who never answered match neither value; `null` means no filter","example":true},"dateRegistrationOnCourse":{"$ref":"#\/components\/schemas\/DateRangeFilter","description":"Date the student was added to a course"},"dateLastEntry":{"$ref":"#\/components\/schemas\/DateRangeFilter","description":"Date of the student's last login. Students who never logged in are excluded"},"courseRestrictions":{"type":["string","null"],"enum":["none","open","closed",null],"description":"Course access period: `none` \u2014 unlimited, `open` \u2014 the access end date has not passed yet,\n`closed` \u2014 the access end date has passed\n","example":"open"},"paidCoursesCondition":{"type":["string","null"],"enum":["=",">=","<=",null],"description":"Comparison for `paidCoursesValue`. Applied only together with it","example":">="},"paidCoursesValue":{"type":["integer","null"],"minimum":1,"description":"Number of the student's courses to compare with. Must be a JSON integer","example":2},"promoCodeIds":{"type":["array","null"],"description":"Only students who have paid with one of these promo codes","items":{"type":"integer"},"example":[701]},"usedPromoCode":{"type":["boolean","null"],"description":"`true` \u2014 the student paid with a promo code; `false` \u2014 the student paid without a promo code or was marked as paid manually.\nStudents who have not paid match neither value\n","example":true},"subscriptionTerms":{"type":["array","null"],"description":"Only students on a subscription tariff with one of these billing periods","items":{"type":"string","enum":["daily","weekly","monthly","quarterly","halfyearly","yearly"]},"example":["monthly","yearly"]},"orderBy":{"type":"string","enum":["firstName","studentStatusOnCourse","studentDateRegistrationOnCourse","studentLastEntry"],"default":"studentDateRegistrationOnCourse","description":"Sort field","example":"firstName"},"sort":{"type":"string","enum":["asc","desc"],"default":"asc","description":"Sort direction","example":"asc"}}},"AuditoryStudentList":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/AuditoryStudent"}},"meta":{"type":"object","required":["total"],"properties":{"total":{"type":"integer","description":"Number of matches before pagination","example":154}}}}},"AuditoryStudent":{"type":"object","required":["id","uuid","email","domainId","schoolId","firstName","lastName","contactFirstName","contactLastName","status","responsibleId","tags","language","avatar","courses","marketingOptIn"],"properties":{"id":{"type":"integer","description":"Student identifier","example":7712345},"uuid":{"type":"string","format":"uuid","description":"Student UUID","example":"0b9f3c1e-5d4a-4e7b-9a61-2f8c7d3e1a90"},"email":{"type":"string","format":"email","description":"Student email","example":"student@example.com"},"domainId":{"type":"integer","description":"Identifier of the school domain","example":2201},"schoolId":{"type":"integer","description":"School identifier","example":3307},"firstName":{"type":"string","description":"First name entered by the student, may be an empty string","example":"Olena"},"lastName":{"type":"string","description":"Last name entered by the student, may be an empty string","example":"Kovalenko"},"contactFirstName":{"type":["string","null"],"description":"First name set by the school owner, `null` if not set","example":"Olena"},"contactLastName":{"type":["string","null"],"description":"Last name set by the school owner, `null` if not set","example":"Kovalenko-Shevchuk"},"status":{"type":"string","enum":["active"],"description":"Student status. Only active students are returned","example":"active"},"responsibleId":{"type":"integer","description":"Identifier of the account owner","example":8945612},"tags":{"type":"array","description":"Contact tag identifiers of the student","items":{"type":"integer"},"example":[50213]},"language":{"type":"string","description":"Student language","example":"uk_UA"},"avatar":{"type":["string","null"],"description":"Avatar URL, `null` if not set","example":null},"courses":{"type":"array","description":"Courses the student is on","items":{"$ref":"#\/components\/schemas\/AuditoryStudentCourse"}},"marketingOptIn":{"type":["boolean","null"],"description":"Marketing consent, `null` if the student never answered","example":true}}},"AuditoryStudentCourse":{"type":"object","required":["courseId","courseName","coverImage","studentStatus","paymentStatus","promoCode","discount","studentDateRegistrationOnCourse","studentLastEntry","courseAvailableDate","hasPaidTariff","courseTariffId","courseTariffName","studentTariffStatus","subscriptionStatus"],"properties":{"courseId":{"type":"integer","description":"Course identifier","example":12571},"courseName":{"type":"string","description":"Course name","example":"Python for beginners"},"coverImage":{"type":["string","null"],"description":"Course cover image URL","example":"https:\/\/cdn.example.com\/edu\/covers\/12571.png"},"studentStatus":{"type":"string","enum":["registered","inProgress","success","failed","certificated"],"description":"Status of the student on the course","example":"inProgress"},"paymentStatus":{"type":["string","null"],"enum":["complete","closed",null],"description":"Status of the student's successful payment for the course, `null` if there is none","example":"complete"},"promoCode":{"type":["string","null"],"description":"Promo code used in the payment","example":"AUTUMN10"},"discount":{"type":["integer","null"],"description":"Discount of the promo code","example":10},"studentDateRegistrationOnCourse":{"type":["string","null"],"format":"date-time","description":"Date the student was added to the course, UTC","example":"2026-09-01T08:15:00.000000Z"},"studentLastEntry":{"type":["string","null"],"format":"date-time","description":"Date of the student's last login, UTC; `null` if they never logged in","example":"2026-10-08T17:42:10.000000Z"},"courseAvailableDate":{"type":["string","null"],"format":"date-time","description":"End of the student's access to the course, UTC; `null` for unlimited access","example":"2026-12-31T21:59:59.000000Z"},"hasPaidTariff":{"type":"boolean","description":"Whether the course has payment methods configured","example":true},"courseTariffId":{"type":["integer","null"],"description":"Tariff of the student on the course, `null` if the student has no tariff","example":4521},"courseTariffName":{"type":["string","null"],"description":"Tariff name","example":"Premium"},"studentTariffStatus":{"type":["string","null"],"enum":["unPaid","paid",null],"description":"Payment status of the student on the tariff, `null` if the student has no tariff","example":"paid"},"subscriptionStatus":{"type":["integer","null"],"enum":[1,2,null],"description":"Subscription status of the student on the course: `1` \u2014 active (access end date is in the future),\n`2` \u2014 stopped; `null` when the student's tariff is not a subscription\n","example":1}}},"SearchCourseStudentsRequest":{"type":"object","description":"`offset` and `limit` are required unless `searchString` is set.","properties":{"offset":{"type":"integer","minimum":0,"description":"Number of matches to skip","example":0},"limit":{"type":"integer","minimum":0,"description":"Maximum number of students to return","example":20},"searchString":{"type":"string","description":"`meta.searchString` from a previous response. Repeats that search; all other fields are ignored\n","example":"eyJjb3Vyc2VJZCI6MTI1NzEsIm9mZnNldCI6MCwibGltaXQiOjIwfQ=="},"firstName":{"type":"string","description":"Substring of the first name or the contact first name","example":"Ole"},"lastName":{"type":"string","description":"Substring of the last name or the contact last name","example":"Kova"},"email":{"type":"string","description":"Substring of the email","example":"@example.com"},"courseStatus":{"type":"array","description":"Statuses of the student on the course","items":{"type":"string","enum":["registered","inProgress","success","failed","certificated","deletedFromCourse"]},"example":["inProgress","success"]},"tags":{"type":"array","description":"Contact tag identifiers (see `listTags`)","items":{"type":"integer"},"example":[50213,50214]},"tagsCondition":{"type":["string","null"],"enum":["all","any",null],"default":"any","description":"`any` \u2014 the student has at least one of `tags`, `all` \u2014 the student has every tag","example":"any"},"lessonId":{"type":"integer","description":"Only students who have started this lesson and have not completed it yet","example":90211},"isPaid":{"type":"boolean","description":"`true` \u2014 the student's tariff is paid; `false` \u2014 not paid or no tariff","example":true},"marketingOptIn":{"type":["boolean","null"],"description":"Marketing consent of the student. Students who never answered match neither value; `null` means no filter","example":true},"dateRegistrationOnCourse":{"$ref":"#\/components\/schemas\/DateRangeFilter","description":"Date the student was added to the course"},"dateLastEntry":{"$ref":"#\/components\/schemas\/DateRangeFilter","description":"Date of the student's last login. Students who never logged in are excluded"},"responsibleIds":{"type":["array","null"],"description":"Identifiers of users responsible for the student on this course, personally or through the student's group.\nA `null` item matches students without a responsible user\n","items":{"type":["integer","null"]},"example":[8945613]},"groupsIds":{"type":["array","null"],"description":"Group identifiers (see `listCourseGroups`). A `null` item matches students without a group on this course","items":{"type":["integer","null"]},"example":[3145]},"tariffIds":{"type":["array","null"],"description":"Course tariff identifiers. `-1` matches students without a tariff","items":{"type":"integer"},"example":[4521,-1]},"withoutTariff":{"type":["boolean","null"],"description":"`true` \u2014 only students without a tariff, `false` \u2014 only students with a tariff. Must not be sent together with `tariffIds`","example":true},"progress":{"$ref":"#\/components\/schemas\/StudentProgressFilter"},"courseRestrictions":{"type":["string","null"],"enum":["none","open","closed",null],"description":"Course access period: `none` \u2014 unlimited, `open` \u2014 the access end date has not passed yet,\n`closed` \u2014 the access end date has passed\n","example":"open"},"orderBy":{"type":"string","enum":["firstName","studentStatusOnCourse","studentDateRegistrationOnCourse","studentLastEntry","gamificationRating"],"default":"studentDateRegistrationOnCourse","description":"Sort field. `gamificationRating` sorts only when gamification is enabled for the school","example":"studentLastEntry"},"sort":{"type":"string","enum":["asc","desc"],"default":"asc","description":"Sort direction","example":"desc"},"promoCodeIds":{"type":["array","null"],"description":"Only students whose last payment for the course used one of these promo codes","items":{"type":"integer"},"example":[701]},"usedPromoCode":{"type":["boolean","null"],"description":"`true` \u2014 the student paid with a promo code; `false` \u2014 the student paid without a promo code or was marked as paid manually.\nStudents who have not paid match neither value\n","example":true},"studentIds":{"type":["array","null"],"description":"Only students with these identifiers","items":{"type":"integer"},"example":[7712345,7712346]}}},"DateRangeFilter":{"type":["object","null"],"description":"Inclusive date range. Both bounds are required when the filter is set. Dates are parsed in UTC;\na date without time means 00:00:00, so use `2026-01-31 23:59:59` to include the whole last day\n","properties":{"dateFrom":{"type":"string","description":"Range start, any date format parsable by PHP (e.g. `2026-01-01` or `2026-01-01T00:00:00Z`)","example":"2026-01-01 00:00:00"},"dateTo":{"type":"string","description":"Range end, not earlier than `dateFrom`","example":"2026-01-31 23:59:59"}}},"StudentProgressFilter":{"type":["object","null"],"description":"Progress filter. Available only on a paid user tariff","properties":{"lessons":{"type":["array","null"],"description":"Identifiers of lessons the student has completed","items":{"type":"integer"},"example":[90211,90212]},"tests":{"type":["array","null"],"description":"Identifiers of tests the student has passed","items":{"type":"integer"},"example":[5120]},"forms":{"type":["array","null"],"description":"Identifiers of forms the student has completed","items":{"type":"integer"},"example":[330]},"certificates":{"type":["array","null"],"description":"Identifiers of certificate sections the student has received","items":{"type":"integer"},"example":[18]},"condition":{"type":["string","null"],"enum":["all","any",null],"description":"`all` \u2014 the student matches every listed item, `any` \u2014 at least one","example":"all"}}},"CourseStudentList":{"type":"object","required":["data","meta"],"properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/CourseStudent"}},"meta":{"type":"object","required":["searchString","total"],"properties":{"searchString":{"type":"string","description":"Encoded filters of this search, for `searchString` or `markStudentsAsPaid`","example":"eyJjb3Vyc2VJZCI6MTI1NzEsIm9mZnNldCI6MCwibGltaXQiOjIwfQ=="},"total":{"type":"integer","description":"Number of matches before pagination","example":154}}}}},"CourseStudent":{"type":"object","required":["id","uuid","email","domainId","schoolId","firstName","lastName","contactFirstName","contactLastName","status","responsibleId","tags","language","avatar","studentStatusOnCourse","courseAvailableDate","courseAvailableTimezone","studentDateRegistrationOnCourse","studentLastEntry","promoCode","promoCodeDiscount","groups","responsible","studentTariff","marketingOptIn","gamificationPoints","gamificationRating","subscriptionStatus"],"properties":{"id":{"type":"integer","description":"Student identifier","example":7712345},"uuid":{"type":"string","format":"uuid","description":"Student UUID","example":"0b9f3c1e-5d4a-4e7b-9a61-2f8c7d3e1a90"},"email":{"type":"string","format":"email","description":"Student email","example":"student@example.com"},"domainId":{"type":"integer","description":"Identifier of the school domain","example":2201},"schoolId":{"type":"integer","description":"School identifier","example":3307},"firstName":{"type":"string","description":"First name entered by the student, may be an empty string","example":"Olena"},"lastName":{"type":"string","description":"Last name entered by the student, may be an empty string","example":"Kovalenko"},"contactFirstName":{"type":["string","null"],"description":"First name set by the school owner, `null` if not set","example":"Olena"},"contactLastName":{"type":["string","null"],"description":"Last name set by the school owner, `null` if not set","example":"Kovalenko-Shevchuk"},"status":{"type":"string","enum":["active"],"description":"Student status. Only active students are returned","example":"active"},"responsibleId":{"type":"integer","description":"Identifier of the account owner","example":8945612},"tags":{"type":"array","description":"Contact tag identifiers of the student","items":{"type":"integer"},"example":[50213]},"language":{"type":"string","description":"Student language","example":"uk_UA"},"avatar":{"type":["string","null"],"description":"Avatar URL, `null` if not set","example":null},"studentStatusOnCourse":{"type":"string","enum":["registered","inProgress","success","failed","certificated","deletedFromCourse"],"description":"Status of the student on the course","example":"inProgress"},"courseAvailableDate":{"type":["string","null"],"format":"date-time","description":"End of the student's access to the course, UTC; `null` for unlimited access","example":"2026-12-31T21:59:59.000000Z"},"courseAvailableTimezone":{"type":["string","null"],"description":"Timezone in which `courseAvailableDate` was set","example":"Europe\/Kyiv"},"studentDateRegistrationOnCourse":{"type":"string","format":"date-time","description":"Date the student was added to the course, UTC","example":"2026-09-01T08:15:00.000000Z"},"studentLastEntry":{"type":["string","null"],"format":"date-time","description":"Date of the student's last login, UTC; `null` if they never logged in","example":"2026-10-08T17:42:10.000000Z"},"promoCode":{"type":["string","null"],"description":"Promo code used in the student's last payment for the course","example":"AUTUMN10"},"promoCodeDiscount":{"oneOf":[{"$ref":"#\/components\/schemas\/PromoCodeDiscount"},{"type":"null"}],"description":"Discount of `promoCode`, `null` when there is no promo code"},"groups":{"type":"array","description":"Groups of the student","items":{"$ref":"#\/components\/schemas\/StudentGroupMembership"}},"responsible":{"type":"array","description":"Users personally responsible for the student","items":{"$ref":"#\/components\/schemas\/StudentResponsible"}},"studentTariff":{"oneOf":[{"$ref":"#\/components\/schemas\/StudentTariff"},{"type":"null"}],"description":"Tariff of the student on the course, `null` if the student has no tariff"},"marketingOptIn":{"type":["boolean","null"],"description":"Marketing consent, `null` if the student never answered","example":true},"gamificationPoints":{"type":["integer","null"],"description":"Gamification points on the course, `null` when gamification is disabled for the school","example":120},"gamificationRating":{"type":["integer","null"],"description":"Position in the course rating starting from 1, `null` when gamification is disabled or the student has no points","example":3},"subscriptionStatus":{"type":["integer","null"],"enum":[1,2,null],"description":"Subscription status of the student on the course: `1` \u2014 active (access end date is in the future),\n`2` \u2014 stopped; `null` when the student's tariff is not a subscription\n","example":1}}},"PromoCodeDiscount":{"type":"object","required":["value","type","currency"],"properties":{"value":{"type":["string","null"],"description":"Discount size as a string","example":"10"},"type":{"type":"string","description":"Discount type","example":"percentage"},"currency":{"type":["string","null"],"description":"Payment currency","example":"UAH"}}},"StudentGroupMembership":{"type":"object","required":["groupId","courseId","groupName","groupColor","responsibleUserId"],"properties":{"groupId":{"type":"integer","description":"Group identifier","example":3145},"courseId":{"type":"integer","description":"Course of the group","example":12571},"groupName":{"type":"string","description":"Group name","example":"Spring stream"},"groupColor":{"type":["string","null"],"description":"Group color as a hex code","example":"#4a90e2"},"responsibleUserId":{"type":["integer","null"],"description":"User responsible for the group, `null` if not assigned","example":8945613}}},"StudentResponsible":{"type":"object","required":["courseId","responsibleUserId"],"properties":{"courseId":{"type":"integer","description":"Course identifier","example":12571},"responsibleUserId":{"type":"integer","description":"Responsible user identifier","example":8945613}}},"StudentTariff":{"type":"object","required":["id","courseId","name","isMain","isPaid","studentTariffStatus","courseTariffSetting","pricingType"],"properties":{"id":{"type":"integer","description":"Course tariff identifier","example":4521},"courseId":{"type":"integer","description":"Course identifier","example":12571},"name":{"type":"string","description":"Tariff name","example":"Premium"},"isMain":{"type":"boolean","description":"Whether this is the main tariff of the course","example":false},"isPaid":{"type":"boolean","description":"Whether the tariff is paid (not free)","example":true},"studentTariffStatus":{"type":"string","enum":["unPaid","paid"],"description":"Payment status of the student on the tariff","example":"paid"},"courseTariffSetting":{"oneOf":[{"$ref":"#\/components\/schemas\/CourseTariffSetting"},{"type":"null"}],"description":"Availability settings of the tariff, `null` if not configured"},"pricingType":{"type":["integer","null"],"enum":[1,2,3,null],"description":"Pricing type of the tariff: `1` \u2014 free, `2` \u2014 one-time payment, `3` \u2014 subscription","example":3}}},"MarkStudentsAsPaidRequest":{"type":"object","description":"Either `ids` or `searchString` must be set. If both are set, `searchString` is used.","properties":{"ids":{"type":"array","description":"Identifiers of the students to mark as paid. Each item must be a JSON integer","items":{"type":"integer"},"example":[7712345,7712346]},"searchString":{"type":"string","description":"Student filter returned in `meta.searchString` by `searchCourseStudents`.\nSelects all students matching that filter, without pagination\n","example":"eyJjb3Vyc2VJZCI6MTI1NzEsIm9mZnNldCI6MCwibGltaXQiOjIwfQ=="}}},"UpdateStudentsAvailabilityDateRequest":{"type":"object","description":"Exactly one of `ids` or `searchString` must be set, and exactly one of `availabilityDate` or `extendDays`\nmust be set; sending both fields of a pair is rejected with `422`.\n`availabilityDate` must be present when `extendDays` is absent: an explicit `null` removes the date,\na missing field is a validation error.\n","properties":{"ids":{"type":"array","maxItems":500,"description":"Identifiers of the students whose access date is changed, up to 500 per request. Each item must be a JSON integer","items":{"type":"integer"},"example":[7712345,7712346]},"searchString":{"type":"string","description":"Student filter returned in `meta.searchString` by `searchCourseStudents`.\nSelects all students matching that filter, without pagination\n","example":"eyJjb3Vyc2VJZCI6MTI1NzEsIm9mZnNldCI6MCwibGltaXQiOjIwfQ=="},"availabilityDate":{"type":["string","null"],"format":"date-time","description":"Moment until which the students can access the course; converted to UTC before saving\n(a value with an offset such as `+03:00` is honoured). `null` removes the date (unlimited access).\nMutually exclusive with `extendDays`; requires `timezone`\n","example":"2026-11-01T00:00:00Z"},"extendDays":{"type":"integer","minimum":1,"maximum":999,"description":"Number of days to add to each student's current access date when it is in the future,\notherwise to the current moment. Mutually exclusive with `availabilityDate`\n","example":7},"timezone":{"type":"string","description":"Required with `availabilityDate`; optional with `extendDays` (the student's current timezone is kept). Must be a valid IANA timezone identifier","example":"Europe\/Kyiv"}}},"StudentMessenger":{"type":"object","required":["typeId","botId","contactId"],"properties":{"typeId":{"type":"integer","description":"Messenger type identifier","example":1},"botId":{"type":"string","maxLength":255,"description":"Bot identifier in the messenger service","example":"64f1c2a9e4b0a1b2c3d4e5f6"},"contactId":{"type":"string","description":"Contact identifier in the messenger service","example":"64f1c2a9e4b0a1b2c3d4e5f7"},"internalId":{"type":"integer","default":0,"description":"Contact identifier inside the messenger","example":123456789},"botCredentials":{"type":"string","maxLength":255,"default":"","description":"Bot credentials","example":"bot-credentials"}}},"Student":{"type":"object","required":["id","uuid","firstName","lastName","status","responsibleId","email","domainId","language","avatar","schoolId"],"properties":{"id":{"type":"integer","description":"Student identifier","example":7712345},"uuid":{"type":"string","format":"uuid","description":"Student UUID","example":"0b9f3c1e-5d4a-4e7b-9a61-2f8c7d3e1a90"},"firstName":{"type":"string","description":"First name, may be an empty string","example":"Olena"},"lastName":{"type":"string","description":"Last name, may be an empty string","example":"Kovalenko"},"status":{"type":"string","enum":["active"],"description":"Student status. Only active students are returned","example":"active"},"responsibleId":{"type":"integer","description":"Identifier of the account owner","example":8945612},"email":{"type":"string","format":"email","description":"Student email","example":"student@example.com"},"domainId":{"type":"integer","description":"Identifier of the school domain","example":2201},"language":{"type":"string","description":"Student language","example":"uk_UA"},"avatar":{"type":["string","null"],"description":"Avatar URL, `null` if not set","example":null},"schoolId":{"type":"integer","description":"School identifier","example":3307}}},"CreateCourseRequest":{"type":"object","required":["name","schoolId"],"properties":{"name":{"type":"string","minLength":3,"maxLength":255,"description":"Course name. Tabs, line breaks and control characters are replaced with spaces","example":"Python for beginners"},"schoolId":{"type":"integer","description":"Identifier of the school to create the course in. Must be a JSON integer; the school must belong to the user","example":3307}}},"UpdateCourseRequest":{"type":"object","required":["name","status"],"properties":{"name":{"type":"string","minLength":3,"maxLength":255,"description":"Course name. Tabs, line breaks and control characters are replaced with spaces","example":"Python for beginners"},"status":{"type":"string","enum":["inProgress","inactive","planned"],"description":"Course status. Validated as optional, but the request fails with `500` when it is omitted or `null`, so always send it.\nMoving an inactive course to `inProgress` for the first time sets its activation date\n","example":"inProgress"},"startDate":{"type":["string","null"],"format":"date-time","description":"Course start date. Validated against the current course status and `status`","example":"2026-01-15T09:00:00"},"endDate":{"type":["string","null"],"format":"date-time","description":"Course end date, must be after `startDate`","example":"2026-12-31T21:59:59"},"timezone":{"type":["string","null"],"description":"Timezone of the course dates","example":"Europe\/Kyiv"},"isLinear":{"type":["boolean","null"],"default":false,"description":"Lessons must be completed in order. Omitted or `null` means `false`","example":false},"completionCriterion":{"type":["string","null"],"enum":["none","lessonsCompleted","testPassed","lessonsCompletedTestPassed","withoutEnding",null],"default":"lessonsCompleted","description":"What the student must do to complete the course. Omitted or `null` means `lessonsCompleted`","example":"lessonsCompleted"},"passingScore":{"type":["integer","null"],"description":"Minimum test score to pass the course. Not validated; must be an integer or `null`","example":70},"coverImage":{"type":["string","null"],"description":"Cover image URL","example":"https:\/\/cdn.example.com\/edu\/courses\/12571\/cover.png"},"redirectUrl":{"type":["string","null"],"format":"uri","minLength":5,"maxLength":512,"description":"Redirect URL after successful completion","example":"https:\/\/example.com\/thank-you"},"failedRedirectUrl":{"type":["string","null"],"format":"uri","minLength":5,"maxLength":512,"description":"Redirect URL after failed completion","example":"https:\/\/example.com\/try-again"},"categoriesIds":{"type":"array","description":"Identifiers of existing categories. Replaces the attached categories; omit to keep them unchanged","items":{"type":"integer"},"example":[14,27]},"groupId":{"type":["integer","null"],"description":"Course group of the course's school (see `School.groups`). Omitted or `null` removes the course from its group","example":610}}},"DuplicateCourseRequest":{"type":"object","required":["name","copyPage"],"properties":{"name":{"type":"string","minLength":3,"maxLength":255,"description":"Name of the copy","example":"Python for beginners (copy)"},"copyPage":{"type":"boolean","description":"Create a course page for the copy. Not available for LMS courses","example":true},"slug":{"type":["string","null"],"maxLength":64,"pattern":"^(?=.{1,63}$)[a-z0-9]+(?:[-_\/][a-z0-9]+)*$","description":"URL of the new course page. Required when `copyPage` is `true`; must be free in the school","example":"python-basics-2"}}},"CourseDetails":{"description":"Course with its settings","allOf":[{"$ref":"#\/components\/schemas\/Course"},{"type":"object","required":["courseSettings"],"properties":{"courseSettings":{"description":"Course settings. An empty array `[]` (not an object) is returned when the course has no settings","oneOf":[{"$ref":"#\/components\/schemas\/CourseSettings"},{"type":"array","maxItems":0}]}}}]},"CourseSettings":{"type":"object","required":["id","courseId","theme","language","showFeedbacksInCourse","showFeedbacksOnLanding","recommendedCourses","isRecommend","recommendInAllCoursePage","isLms","hideOrder","pathToCertificateDirectory","collectFeedbacks","unfolded"],"properties":{"id":{"type":["integer","null"],"description":"Settings identifier","example":11020},"courseId":{"type":["integer","null"],"description":"Course identifier","example":12571},"theme":{"type":"string","description":"Course theme encoded as a JSON string","example":"{\"color\":\"#4a90e2\"}"},"language":{"type":["string","null"],"description":"Course language","example":"uk"},"showFeedbacksInCourse":{"type":"string","enum":["none","showAll","showNotLessThanThree","showNotLessThanFour","showNotLessThanFive"],"description":"Which student feedbacks are shown inside the course","example":"none"},"showFeedbacksOnLanding":{"type":"string","enum":["none","showAll","showNotLessThanThree","showNotLessThanFour","showNotLessThanFive"],"description":"Which student feedbacks are shown on the course landing","example":"showAll"},"recommendedCourses":{"type":["array","null"],"description":"Identifiers of courses recommended after this one","items":{"type":"integer"},"example":[12572]},"isRecommend":{"type":"boolean","description":"Recommend other courses after this one","example":false},"recommendInAllCoursePage":{"type":"boolean","description":"Show recommendations on the page with all courses","example":false},"isLms":{"type":"boolean","description":"The course belongs to an LMS school","example":false},"hideOrder":{"type":"boolean","description":"Hide lesson numbers","example":false},"pathToCertificateDirectory":{"type":["string","null"],"description":"Storage directory of the course certificates","example":null},"collectFeedbacks":{"type":"boolean","description":"Collect student feedbacks","example":true},"unfolded":{"type":"boolean","description":"Show the course structure unfolded","example":true}}},"BatchCopyCourseContentRequest":{"type":"object","required":["newCourseId"],"properties":{"newCourseId":{"type":"integer","description":"Identifier of the target course. Must belong to the user.\nIf `sections` is empty, the target course must already have at least one section\n","example":12572},"newSectionId":{"type":["integer","null"],"description":"Section of the target course to copy top-level `lessonsIds`, `testsIds`, `certificateSectionsIds` and `formsIds` into","example":8805},"sections":{"type":["array","null"],"description":"Sections to copy together with the selected content","items":{"$ref":"#\/components\/schemas\/BatchCopySection"}},"lessonsIds":{"type":["array","null"],"description":"Lessons to copy","items":{"type":"integer"},"example":[90211]},"testsIds":{"type":["array","null"],"description":"Tests to copy","items":{"type":"integer"},"example":[5120]},"certificateSectionsIds":{"type":["array","null"],"description":"Certificate sections to copy","items":{"type":"integer"},"example":[1305]},"formsIds":{"type":["array","null"],"description":"Forms to copy","items":{"type":"integer"},"example":[2210]}}},"BatchCopySection":{"type":"object","required":["id"],"properties":{"id":{"type":"integer","description":"Section identifier","example":8801},"lessonsIds":{"type":["array","null"],"description":"Lessons of the section to copy with it","items":{"type":"integer"},"example":[90211,90212]},"testsIds":{"type":["array","null"],"description":"Tests of the section to copy with it","items":{"type":"integer"},"example":[5120]},"certificateSectionsIds":{"type":["array","null"],"description":"Certificate sections of the section to copy with it","items":{"type":"integer"},"example":[]},"formsIds":{"type":["array","null"],"description":"Forms of the section to copy with it","items":{"type":"integer"},"example":[]}}},"BatchUpdateCourseContentAccessRequest":{"type":"object","properties":{"sections":{"type":["object","null"],"description":"Sections to change","properties":{"ids":{"type":"array","items":{"type":"integer"},"example":[8801]},"status":{"type":"string","enum":["closed","opened","planned","hidden"],"example":"opened"}}},"lessons":{"type":["object","null"],"description":"Lessons to change","properties":{"ids":{"type":"array","items":{"type":"integer"},"example":[90211,90212]},"status":{"type":"string","enum":["closed","opened","deleted","planned","hidden"],"example":"closed"}}},"tests":{"type":["object","null"],"description":"Tests to change","properties":{"ids":{"type":"array","items":{"type":"integer"},"example":[5120]},"status":{"type":"string","enum":["blocked","active","inactive","planned","hidden"],"example":"active"}}},"certificateSections":{"type":["object","null"],"description":"Certificate sections to change","properties":{"ids":{"type":"array","items":{"type":"integer"},"example":[1305]},"status":{"type":"string","enum":["inactive","active","planned","hidden"],"example":"active"}}},"forms":{"type":["object","null"],"description":"Forms to change","properties":{"ids":{"type":"array","items":{"type":"integer"},"example":[2210]},"status":{"type":"string","enum":["inactive","active","planned","hidden"],"example":"hidden"}}},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date for the `planned` status. Required when `timezone` is set; must not be in the past","example":"2026-11-01T09:00:00"},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`","example":"Europe\/Kyiv"}}},"BatchDeleteCourseContentRequest":{"type":"object","properties":{"sectionsIds":{"type":["array","null"],"description":"Sections to delete","items":{"type":"integer"},"example":[8801]},"lessonsIds":{"type":["array","null"],"description":"Lessons to delete","items":{"type":"integer"},"example":[90211]},"testsIds":{"type":["array","null"],"description":"Tests to delete","items":{"type":"integer"},"example":[5120]},"certificateSectionIds":{"type":["array","null"],"description":"Certificate sections to delete. Note the singular `certificateSection` in the key, unlike the copy operation","items":{"type":"integer"},"example":[1305]},"formsIds":{"type":["array","null"],"description":"Forms to delete","items":{"type":"integer"},"example":[2210]}}},"CourseTariffRequest":{"type":"object","required":["name","isMain","pricingType","status"],"properties":{"name":{"type":"string","minLength":3,"maxLength":100,"description":"Tariff name","example":"Premium"},"isMain":{"type":"boolean","description":"Required, but ignored \u2014 the tariff is always saved as not main","example":false},"pricingType":{"type":"integer","enum":[1,2,3],"description":"Pricing type: `1` \u2014 free, `2` \u2014 one-time payment, `3` \u2014 subscription","example":2},"status":{"type":"string","enum":["active","inactive"],"description":"Tariff status","example":"active"},"succeedRedirectUrl":{"type":["string","null"],"format":"uri","maxLength":512,"description":"Redirect URL after successful payment. On update an omitted field keeps the current value","example":"https:\/\/example.com\/payment-success"},"failedRedirectUrl":{"type":["string","null"],"format":"uri","maxLength":512,"description":"Redirect URL after failed payment. On update an omitted field keeps the current value","example":"https:\/\/example.com\/payment-failed"}}},"ShortCourseTariff":{"type":"object","required":["id","courseId","status","name","isPaid","isMain","pricingType","wasStarted","succeedRedirectUrl","failedRedirectUrl","order"],"properties":{"id":{"type":"integer","description":"Tariff identifier","example":4521},"courseId":{"type":"integer","description":"Course identifier","example":12571},"status":{"type":"string","enum":["active","inactive"],"description":"Tariff status","example":"active"},"name":{"type":"string","description":"Tariff name","example":"Premium"},"isPaid":{"type":"boolean","description":"The tariff has at least one payment method","example":false},"isMain":{"type":"boolean","description":"The default tariff of the course","example":false},"pricingType":{"type":["integer","null"],"enum":[1,2,3,null],"description":"Pricing type: `1` \u2014 free, `2` \u2014 one-time payment, `3` \u2014 subscription","example":2},"wasStarted":{"type":"boolean","description":"The tariff has been active at least once","example":false},"succeedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after successful payment","example":"https:\/\/example.com\/payment-success"},"failedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after failed payment","example":"https:\/\/example.com\/payment-failed"},"order":{"type":["integer","null"],"description":"Display order","example":2}}},"ReorderCourseTariffsRequest":{"type":"object","required":["tariffs"],"properties":{"tariffs":{"type":"array","description":"Tariff identifiers in the new display order. Every tariff must belong to the course; tariffs that are not listed keep their position","items":{"type":"integer"},"example":[4521,4520,4522]}}},"CourseTariffDetailsList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"$ref":"#\/components\/schemas\/CourseTariffDetails"}}}},"CourseTariffDetails":{"type":"object","required":["id","courseId","status","name","isMain","isPaid","pricingType","wasStarted","order","succeedRedirectUrl","failedRedirectUrl","countOfStudents","courseAccessRestrictionSettings","paymentMethods","studentBaseStateSetting","contentAccesses","functionalityAccesses","courseTariffSetting","costCalculationPolicies","tariffRenewals","advertisingText"],"properties":{"id":{"type":"integer","description":"Tariff identifier","example":4521},"courseId":{"type":"integer","description":"Course identifier","example":12571},"status":{"type":"string","enum":["active","inactive"],"description":"Tariff status","example":"active"},"name":{"type":"string","description":"Tariff name","example":"Premium"},"isMain":{"type":"boolean","description":"The default tariff of the course","example":true},"isPaid":{"type":"boolean","description":"The tariff has at least one payment method","example":true},"pricingType":{"type":["integer","null"],"enum":[1,2,3,null],"description":"Pricing type: `1` \u2014 free, `2` \u2014 one-time payment, `3` \u2014 subscription","example":2},"wasStarted":{"type":"boolean","description":"The tariff has been active at least once","example":true},"order":{"type":["integer","null"],"description":"Display order","example":1},"succeedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after successful payment","example":"https:\/\/example.com\/payment-success"},"failedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after failed payment","example":"https:\/\/example.com\/payment-failed"},"countOfStudents":{"type":["integer","null"],"minimum":1,"description":"Number of students on the tariff. `null` when there are no students (never `0`)","example":48},"courseAccessRestrictionSettings":{"description":"Course access duration of the tariff, `null` if not configured","oneOf":[{"$ref":"#\/components\/schemas\/TariffAccessRestriction"},{"type":"null"}]},"paymentMethods":{"type":["array","null"],"items":{"$ref":"#\/components\/schemas\/TariffPaymentMethod"}},"studentBaseStateSetting":{"description":"Initial state applied to a student enrolled on the tariff, `null` if not configured","oneOf":[{"$ref":"#\/components\/schemas\/TariffStudentBaseStateSetting"},{"type":"null"}]},"contentAccesses":{"type":"array","description":"Course content available on the tariff","items":{"$ref":"#\/components\/schemas\/TariffContentAccess"}},"functionalityAccesses":{"type":["array","null"],"description":"Functionality available on the tariff","items":{"$ref":"#\/components\/schemas\/TariffFunctionality"}},"courseTariffSetting":{"description":"Availability settings of the tariff, `null` if not configured","oneOf":[{"$ref":"#\/components\/schemas\/TariffSettings"},{"type":"null"}]},"costCalculationPolicies":{"type":["array","null"],"description":"Upgrade price rules of the tariff","items":{"$ref":"#\/components\/schemas\/TariffCostCalculationPolicy"}},"tariffRenewals":{"type":["array","null"],"items":{"$ref":"#\/components\/schemas\/TariffRenewalItem"}},"advertisingText":{"description":"Advertising text of the tariff, `null` if not set","oneOf":[{"$ref":"#\/components\/schemas\/TariffAdvertisingText"},{"type":"null"}]}}},"TariffAccessRestriction":{"type":"object","required":["restrictedDays","restrictedToDate","timezone"],"properties":{"restrictedDays":{"type":["integer","null"],"description":"Access is limited to this number of days after enrollment, `null` if not limited by days","example":90},"restrictedToDate":{"type":["string","null"],"format":"date-time","description":"Access is limited until this moment, UTC; `null` if not limited by a fixed date","example":"2026-12-31T21:59:59.000000Z"},"timezone":{"type":["string","null"],"description":"Timezone of the restriction","example":"Europe\/Kyiv"}}},"TariffPaymentMethod":{"type":"object","required":["id","name","price","currency","paymentId","paymentType","recurringMode","rro","paymentDescription","products"],"properties":{"id":{"type":"integer","description":"Payment method identifier (`paymentId` in the payment method paths)","example":3920},"name":{"type":"string","description":"Payment method name, taken from the payment system","example":"Card payment"},"price":{"type":"number","description":"Price","example":1500},"currency":{"type":"string","description":"Currency code, taken from the payment system","example":"UAH"},"paymentId":{"type":"string","description":"Key of the payment system connected in the user's account","example":"1c9f4e2a-5b7d-4f0e-9a51-2d6c1e8b7f30"},"paymentType":{"type":"string","description":"Payment provider (see `PaymentMethod.paymentType`)","example":"Stripe"},"recurringMode":{"type":["string","null"],"enum":["daily","weekly","monthly","quarterly","halfyearly","yearly",null],"description":"Billing period of a subscription, `null` for a one-time payment method","example":null},"rro":{"type":["string","null"],"description":"Product code for the fiscal receipt (used by Monobank and LiqPay)","example":null},"paymentDescription":{"type":["string","null"],"description":"Payment description","example":"Payment for the Python for beginners course"},"products":{"type":"array","description":"Products linked to the tariff of this payment method","items":{"$ref":"#\/components\/schemas\/PaymentMethodProduct"}}}},"PaymentMethodProduct":{"type":"object","required":["id","courseTariffId","productId"],"properties":{"id":{"type":"integer","example":215},"courseTariffId":{"type":"integer","description":"Tariff identifier","example":4521},"productId":{"type":"integer","description":"Product identifier","example":3301}}},"TariffStudentBaseStateSetting":{"type":"object","required":["group","responsible","tags","dealCreation"],"properties":{"group":{"type":["integer","null"],"description":"Student group the student is added to","example":3145},"responsible":{"type":["integer","null"],"description":"Responsible user assigned to the student","example":8945613},"tags":{"type":["array","null"],"description":"Tags assigned to the student","items":{"type":"integer"},"example":[50213]},"dealCreation":{"description":"CRM deal created for the student, `null` if disabled","oneOf":[{"$ref":"#\/components\/schemas\/DealCreation"},{"type":"null"}]}}},"TariffContentAccess":{"type":"object","required":["contentType","entityId"],"properties":{"contentType":{"type":"string","enum":["section","lesson","test","certificate","form"],"description":"Type of the course entity","example":"lesson"},"entityId":{"type":"integer","description":"Identifier of the course entity","example":90211}}},"TariffFunctionality":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["chat","audioMessage","stateVideo","homeworkDiscussion"],"description":"Functionality available to students","example":"chat"}}},"TariffSettings":{"type":"object","required":["startDate","endDate","timezone","contentShow","quota"],"properties":{"startDate":{"type":["string","null"],"format":"date-time","description":"Tariff availability start, UTC","example":"2026-09-01T06:00:00.000000Z"},"endDate":{"type":["string","null"],"format":"date-time","description":"Tariff availability end, UTC","example":"2026-12-31T21:59:59.000000Z"},"timezone":{"type":["string","null"],"description":"Timezone of the dates","example":"Europe\/Kyiv"},"contentShow":{"type":"boolean","description":"Show content unavailable on the tariff to students","example":true},"quota":{"type":["integer","null"],"description":"Maximum number of students on the tariff, `null` for unlimited","example":100}}},"TariffCostCalculationPolicy":{"type":"object","required":["type","courseTariff","status","state"],"properties":{"type":{"type":"integer","enum":[1,2],"description":"Price calculation: `1` \u2014 automatically, `2` \u2014 manual","example":2},"courseTariff":{"type":"integer","description":"Source tariff identifier of the rule","example":4520},"status":{"type":"integer","enum":[1,2],"description":"`1` \u2014 inactive, `2` \u2014 active","example":2},"state":{"type":["number","null"],"description":"Manual upgrade price","example":49.99}}},"TariffRenewalItem":{"type":"object","required":["id","name","status","days","amount","succeedRedirectUrl","failedRedirectUrl","dealCreation"],"properties":{"id":{"type":"integer","description":"Renewal identifier","example":702},"name":{"type":"string","description":"Renewal name","example":"Extend for 30 days"},"status":{"type":"string","enum":["active","inactive"],"example":"active"},"days":{"type":"integer","description":"Number of days the access is extended by","example":30},"amount":{"type":["number","null"],"description":"Renewal price","example":19.99},"succeedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after successful payment","example":"https:\/\/example.com\/renewal-success"},"failedRedirectUrl":{"type":["string","null"],"description":"Redirect URL after failed payment","example":"https:\/\/example.com\/renewal-failed"},"dealCreation":{"description":"CRM deal created on renewal, `null` if disabled","oneOf":[{"$ref":"#\/components\/schemas\/DealCreation"},{"type":"null"}]}}},"TariffAdvertisingText":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"Advertising text","example":"Personal mentor and weekly Q&A sessions"}}},"UpdateTariffFunctionalityAccessRequest":{"type":"object","properties":{"data":{"type":["array","null"],"description":"The full list of functionality to make available on the tariff","items":{"type":"object","required":["type"],"properties":{"type":{"type":"string","enum":["chat","audioMessage","stateVideo","homeworkDiscussion"],"example":"chat"}}}}}},"UpdateTariffContentAccessRequest":{"type":"object","required":["data"],"properties":{"data":{"type":"array","maxItems":500,"description":"The full list of course content to make available on the tariff; an empty array removes all content","items":{"$ref":"#\/components\/schemas\/TariffContentAccess"}}}},"UpdateTariffsEntityAccessRequest":{"type":"object","required":["data"],"properties":{"data":{"type":"array","maxItems":500,"items":{"type":"object","required":["tariffId","entities"],"properties":{"tariffId":{"type":"integer","description":"Tariff identifier. Must be a JSON integer; the tariff must belong to the course","example":4521},"entities":{"type":"array","maxItems":500,"description":"The full list of content available on the tariff. Must be present, may be empty","items":{"type":"object","required":["entityId","entityType"],"properties":{"entityId":{"type":"integer","description":"Identifier of the course entity","example":90211},"entityType":{"type":"string","enum":["section","lesson","test","certificate","form"],"description":"Type of the course entity","example":"lesson"}}}}}}}}},"DeleteCourseTariffRequest":{"type":"object","properties":{"courseTariffIdTo":{"type":["integer","null"],"description":"Active tariff of the same course to move the students to. Required when the deleted tariff has students;\nmust not be sent when it has none\n","example":4520},"markPaid":{"type":["boolean","null"],"default":false,"description":"Mark the moved students' new tariff as paid","example":false},"applyCourseTariffSettings":{"type":["boolean","null"],"default":false,"description":"Apply the settings of the target tariff to the moved students","example":false}}},"UpdateCourseTariffSettingsRequest":{"type":"object","required":["contentShow"],"properties":{"startDate":{"type":["string","null"],"format":"date-time","description":"Tariff availability start","example":"2026-09-01T09:00:00"},"endDate":{"type":["string","null"],"format":"date-time","description":"Tariff availability end, must be after `startDate`","example":"2026-12-31T23:59:59"},"timezone":{"type":["string","null"],"description":"Timezone of the dates","example":"Europe\/Kyiv"},"contentShow":{"type":"boolean","description":"Show content unavailable on the tariff to students","example":true},"quota":{"type":["integer","null"],"minimum":0,"description":"Maximum number of students on the tariff, `null` for unlimited. Cannot be less than the current number of students","example":100}}},"TariffRenewalRequest":{"type":"object","required":["name","status","days"],"properties":{"name":{"type":"string","minLength":1,"maxLength":255,"description":"Renewal name","example":"Extend for 30 days"},"status":{"type":"string","enum":["active","inactive"],"example":"active"},"days":{"type":"integer","minimum":1,"description":"Number of days the access is extended by","example":30},"amount":{"type":["number","null"],"minimum":0.1,"maximum":9999999,"description":"Renewal price","example":19.99},"succeedRedirectUrl":{"type":["string","null"],"format":"uri","maxLength":512,"description":"Redirect URL after successful payment","example":"https:\/\/example.com\/renewal-success"},"failedRedirectUrl":{"type":["string","null"],"format":"uri","maxLength":512,"description":"Redirect URL after failed payment","example":"https:\/\/example.com\/renewal-failed"},"dealCreation":{"description":"CRM deal to create on renewal, `null` to disable.\n`pipelineId` must be a pipeline of the user's CRM and `stepId` a step of that pipeline,\notherwise `422` with `errors[\"dealCreation.pipelineId\"]` \/ `errors[\"dealCreation.stepId\"]` is returned\n(also when the CRM is unavailable and the pipeline cannot be verified).\n","oneOf":[{"$ref":"#\/components\/schemas\/DealCreation"},{"type":"null"}]}}},"UpdateTariffAccessRestrictionRequest":{"type":"object","description":"Either `restrictedDays` (relative) or `restrictedToDate` (absolute) must be present, not both;\nan explicit `null` in the sent field removes the limit. An empty body is rejected with `422`,\nso a misspelled field can never lift the restriction by accident.\n","properties":{"restrictedDays":{"type":["integer","null"],"minimum":1,"maximum":999,"description":"Number of days of access after enrollment, `null` to remove the limit. Mutually exclusive with `restrictedToDate`","example":90},"restrictedToDate":{"type":["string","null"],"format":"date-time","description":"Access is limited until this moment; converted to UTC before saving; must not be in the past; mutually exclusive with `restrictedDays`; requires `timezone`","example":null},"timezone":{"type":["string","null"],"description":"Timezone stored with the restriction. Must be a valid IANA timezone identifier; required with `restrictedToDate`","example":"Europe\/Kyiv"}}},"UpsertTariffAdvertisingTextRequest":{"type":"object","required":["text"],"properties":{"text":{"type":"string","maxLength":10000,"description":"Advertising text","example":"Personal mentor and weekly Q&A sessions"}}},"CreatePaymentMethodRequest":{"type":"object","required":["paymentId","price"],"properties":{"paymentId":{"type":"string","description":"Key of a payment system connected in the user's account","example":"1c9f4e2a-5b7d-4f0e-9a51-2d6c1e8b7f30"},"price":{"type":"number","minimum":0.1,"maximum":9999999,"description":"Price","example":1500},"recurringMode":{"type":"string","enum":["daily","weekly","monthly","quarterly","halfyearly","yearly"],"description":"Billing period. Required for a subscription tariff (`pricingType` `3`) and prohibited for other tariffs","example":"monthly"},"rro":{"type":["string","null"],"description":"Product code for the fiscal receipt (used by Monobank and LiqPay)","example":null},"paymentDescription":{"type":["string","null"],"description":"Payment description","example":"Payment for the Python for beginners course"},"productCategoryId":{"type":["integer","null"],"description":"Product category for the product created together with the payment method","example":41}}},"UpdatePaymentMethodRequest":{"type":"object","required":["paymentId"],"properties":{"paymentId":{"type":"string","description":"Key of a payment system connected in the user's account. Required and validated, but the payment system of the method is not changed","example":"1c9f4e2a-5b7d-4f0e-9a51-2d6c1e8b7f30"},"price":{"type":["number","null"],"minimum":0.1,"maximum":9999999,"description":"New price. Cannot be changed for a started subscription tariff","example":1700},"rro":{"type":["string","null"],"description":"Product code for the fiscal receipt","example":null},"paymentDescription":{"type":["string","null"],"description":"Payment description","example":"Payment for the Python for beginners course"}}},"CreateSectionRequest":{"type":"object","required":["name","order","duration"],"properties":{"name":{"type":"string","maxLength":255,"description":"Section name","example":"Introduction"},"order":{"type":"integer","minimum":1,"maximum":999999,"description":"Position of the section in the course","example":1},"description":{"type":["string","null"],"description":"Section description","example":"Basics of the language"},"duration":{"type":"integer","minimum":0,"maximum":999999999,"description":"Duration of the section","example":0},"status":{"type":["string","null"],"enum":["closed","opened","deleted","planned","hidden",null],"default":"opened","description":"Section status. Omitted or `null` means `opened`; `planned` opens the section at `startDate`","example":"opened"},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date. Required when `timezone` is set; must not be in the past","example":"2026-11-01T09:00:00"},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`. Only on a paid tariff of the user","example":"Europe\/Kyiv"},"preview":{"type":["string","null"],"maxLength":5000,"description":"Preview text. Only on a paid tariff of the user","example":"What you will learn in this section"}}},"UpdateSectionRequest":{"type":"object","required":["name","courseId","order","duration"],"properties":{"name":{"type":"string","maxLength":255,"description":"Section name","example":"Introduction"},"courseId":{"type":"integer","description":"Required and must be a course of the user, but not used \u2014 the section stays in the course from the path. Send the path `courseId`","example":12571},"order":{"type":"integer","minimum":1,"maximum":999999,"description":"Position of the section in the course","example":1},"description":{"type":["string","null"],"description":"Section description","example":"Basics of the language"},"duration":{"type":"integer","minimum":0,"maximum":999999999,"description":"Duration of the section","example":0},"status":{"type":["string","null"],"enum":["closed","opened","planned","hidden",null],"default":"opened","description":"Section status. Omitted or `null` means `opened`","example":"opened"},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date. Required when `timezone` is set; must not be in the past","example":"2026-11-01T09:00:00"},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`. Only on a paid tariff of the user","example":"Europe\/Kyiv"},"preview":{"type":["string","null"],"maxLength":5000,"description":"Preview text. Only on a paid tariff of the user","example":"What you will learn in this section"}}},"Section":{"type":"object","required":["id","name","userId","courseId","order","description","duration","status","startDate","timezone","intervalDate","preview"],"properties":{"id":{"type":"integer","description":"Section identifier","example":8801},"name":{"type":"string","description":"Section name","example":"Introduction"},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"courseId":{"type":"integer","description":"Course identifier","example":12571},"order":{"type":"integer","description":"Position of the section in the course","example":1},"description":{"type":["string","null"],"description":"Section description","example":"Basics of the language"},"duration":{"type":"integer","description":"Duration of the section","example":0},"status":{"type":"string","enum":["closed","opened","deleted","planned","hidden"],"description":"Section status","example":"opened"},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date, UTC","example":null},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`","example":null},"intervalDate":{"type":["integer","null"],"description":"Delay of the opening, set by the course constructor","example":null},"preview":{"type":["string","null"],"description":"Preview text","example":null}}},"LessonContentBlock":{"type":"object","description":"A block of the lesson content as saved by the lesson editor. The structure of the block depends on its type and is stored as is","additionalProperties":true,"example":{"type":"text","value":"Hello"}},"CreateLessonRequest":{"type":"object","required":["name","sectionId","order","content"],"properties":{"name":{"type":"string","maxLength":255,"description":"Lesson name. Tabs, line breaks and control characters are replaced with spaces","example":"Variables"},"sectionId":{"type":"integer","description":"Section of the course to put the lesson in","example":8801},"order":{"type":"integer","minimum":1,"maximum":999999,"description":"Position of the lesson in the section","example":1},"content":{"type":"array","description":"Lesson content blocks","items":{"$ref":"#\/components\/schemas\/LessonContentBlock"}},"status":{"type":["string","null"],"enum":["closed","opened","deleted","planned","hidden",null],"default":"opened","description":"Lesson status. Omitted or `null` means `opened`","example":"opened"},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date. Required when `timezone` is set; must not be in the past","example":"2026-11-01T09:00:00"},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`. Only on a paid tariff of the user","example":"Europe\/Kyiv"},"preview":{"type":["string","null"],"maxLength":5000,"description":"Preview text. Only on a paid tariff of the user","example":null},"isStopLesson":{"type":["boolean","null"],"default":false,"description":"Students cannot go further until they complete this lesson","example":false},"minCompletionTime":{"type":["integer","null"],"minimum":1,"description":"Minimum time a student must spend on the lesson. Only on a paid tariff of the user","example":300}}},"UpdateLessonRequest":{"type":"object","required":["name","sectionId","order","content","isStopLesson"],"properties":{"name":{"type":"string","maxLength":255,"description":"Lesson name. Tabs, line breaks and control characters are replaced with spaces","example":"Variables"},"sectionId":{"type":"integer","description":"Section of the course to put the lesson in","example":8801},"order":{"type":"integer","minimum":1,"maximum":999999,"description":"Position of the lesson in the section","example":1},"content":{"type":"array","description":"Lesson content blocks","items":{"$ref":"#\/components\/schemas\/LessonContentBlock"}},"status":{"type":["string","null"],"enum":["closed","opened","planned","hidden",null],"default":"opened","description":"Lesson status. Omitted or `null` means `opened`","example":"opened"},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date. Required when `timezone` is set; must not be in the past","example":"2026-11-01T09:00:00"},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`. Only on a paid tariff of the user","example":"Europe\/Kyiv"},"preview":{"type":["string","null"],"maxLength":5000,"description":"Preview text. Only on a paid tariff of the user","example":null},"isStopLesson":{"type":"boolean","description":"Students cannot go further until they complete this lesson","example":false},"minCompletionTime":{"type":["integer","null"],"description":"Minimum time a student must spend on the lesson. Only on a paid tariff of the user","example":300}}},"Lesson":{"type":"object","required":["id","name","userId","order","courseId","sectionId","content","startDate","timezone","status","preview","isStopLesson","minCompletionTime"],"properties":{"id":{"type":"integer","description":"Lesson identifier","example":90211},"name":{"type":"string","description":"Lesson name","example":"Variables"},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"order":{"type":"integer","description":"Position of the lesson in the section","example":1},"courseId":{"type":"integer","description":"Course identifier","example":12571},"sectionId":{"type":"integer","description":"Section identifier","example":8801},"content":{"type":"array","description":"Lesson content blocks","items":{"$ref":"#\/components\/schemas\/LessonContentBlock"}},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date, UTC","example":null},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`","example":null},"status":{"type":"string","enum":["closed","opened","deleted","planned","hidden"],"description":"Lesson status","example":"opened"},"preview":{"type":["string","null"],"description":"Preview text","example":null},"isStopLesson":{"type":"boolean","description":"Students cannot go further until they complete this lesson","example":false},"minCompletionTime":{"type":["integer","null"],"description":"Minimum time a student must spend on the lesson","example":null}}},"CourseStructureSection":{"type":"object","required":["id","name","userId","order","courseId","description","duration","status","startDate","timezone","preview","createdAt","availableOnTariffs","lessons"],"properties":{"id":{"type":"integer","description":"Section identifier","example":8801},"name":{"type":"string","description":"Section name","example":"Introduction"},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"order":{"type":"integer","description":"Position of the section in the course","example":1},"courseId":{"type":"integer","description":"Course identifier","example":12571},"description":{"type":["string","null"],"description":"Section description","example":"Basics of the language"},"duration":{"type":"integer","description":"Duration of the section","example":0},"status":{"type":"string","enum":["closed","opened","planned","hidden"],"description":"Section status","example":"opened"},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date, UTC","example":null},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`","example":null},"preview":{"type":["string","null"],"description":"Preview text","example":null},"createdAt":{"type":["string","null"],"format":"date-time","description":"Creation time, UTC","example":"2026-02-10T08:15:00.000000Z"},"availableOnTariffs":{"type":["array","null"],"description":"Not filled by this operation, always `null`","items":[],"example":null},"lessons":{"type":"array","items":{"$ref":"#\/components\/schemas\/CourseStructureLesson"}}}},"CourseStructureLesson":{"type":"object","required":["id","name","userId","order","courseId","sectionId","startDate","timezone","intervalDate","createdAt","status","countStudentsCompletedLesson","haveHomeworks","preview","isStopLesson","minCompletionTime","isFavorite","availableOnTariffs"],"properties":{"id":{"type":"integer","description":"Lesson identifier","example":90211},"name":{"type":"string","description":"Lesson name","example":"Variables"},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"order":{"type":"integer","description":"Position of the lesson in the section","example":1},"courseId":{"type":"integer","description":"Course identifier","example":12571},"sectionId":{"type":"integer","description":"Section identifier","example":8801},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date, UTC","example":null},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`","example":null},"intervalDate":{"type":["integer","null"],"description":"Delay of the opening, set by the course constructor","example":null},"createdAt":{"type":["string","null"],"format":"date-time","description":"Creation time, UTC","example":"2026-02-10T08:20:00.000000Z"},"status":{"type":"string","enum":["closed","opened","planned","hidden"],"description":"Lesson status","example":"opened"},"countStudentsCompletedLesson":{"type":"integer","minimum":0,"description":"Number of students who completed the lesson","example":17},"haveHomeworks":{"type":"boolean","description":"The lesson has a homework task","example":true},"preview":{"type":["string","null"],"description":"Preview text","example":null},"isStopLesson":{"type":"boolean","description":"Students cannot go further until they complete this lesson","example":false},"minCompletionTime":{"type":["integer","null"],"description":"Minimum time a student must spend on the lesson","example":null},"isFavorite":{"type":"boolean","description":"The lesson is marked as favorite","example":false},"availableOnTariffs":{"type":"array","description":"Not filled by this operation, always an empty array","maxItems":0,"items":[],"example":[]}}},"LessonContentList":{"type":"object","required":["data"],"properties":{"data":{"type":"array","items":{"type":"object","required":["id","content"],"properties":{"id":{"type":"integer","description":"Lesson identifier","example":90211},"content":{"type":["array","null"],"description":"Lesson content blocks","items":{"$ref":"#\/components\/schemas\/LessonContentBlock"}}}}}}},"CreateTestRequest":{"type":"object","required":["name","relatedEntityType","relatedEntityId","scorePerQuestion","tries","showAnswers","status","minimumScoreToSuccess"],"properties":{"name":{"type":"string","maxLength":64,"description":"Test name","example":"Final test"},"relatedEntityType":{"type":"string","enum":["course","section","lesson"],"description":"Where the test is placed","example":"section"},"relatedEntityId":{"type":"integer","description":"Identifier of the entity the test is placed in: the course identifier from the path for `course`,\nor a section or lesson of the course. Error key: `courseId.invalid`, `sectionId.invalid` or `lessonId.invalid`\n","example":8801},"order":{"type":["integer","null"],"minimum":0,"description":"Position of the test","example":3},"scorePerQuestion":{"type":"integer","minimum":1,"description":"Score for each correctly answered question","example":1},"tries":{"type":"integer","minimum":0,"description":"Number of attempts, `0` for unlimited","example":3},"minimumScoreToSuccess":{"type":"integer","description":"Minimum score to pass the test. It cannot be greater than `scorePerQuestion` multiplied by the number of items\nin a `questions` array sent in this request body (the array itself is ignored), so without it only `0` is accepted\n","example":0},"showAnswers":{"type":"boolean","description":"Show the correct answers to the student","example":true},"showExplanations":{"type":["boolean","null"],"default":false,"description":"Show answer explanations. Cannot be enabled without `showAnswers`","example":false},"showAnswersAfterCompletion":{"type":["boolean","null"],"default":false,"description":"Show the answers only after the test is completed. Only on a paid tariff of the user","example":false},"randomDirection":{"type":["boolean","null"],"default":false,"description":"Shuffle the questions","example":false},"randomAnswersDirection":{"type":["boolean","null"],"default":false,"description":"Shuffle the answer variants","example":false},"status":{"type":"string","enum":["blocked","active","inactive","planned","hidden"],"description":"Test status","example":"active"},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date. Required when `timezone` is set; must not be in the past","example":"2026-11-01T09:00:00"},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`. Only on a paid tariff of the user","example":"Europe\/Kyiv"},"description":{"type":["string","null"],"maxLength":64535,"description":"Test description","example":"Check what you have learned"},"questionsLimit":{"type":["integer","null"],"minimum":1,"maximum":65535,"description":"Number of questions shown to the student. Only on a paid tariff of the user","example":null},"preview":{"type":["string","null"],"maxLength":5000,"description":"Preview text. Only on a paid tariff of the user","example":null},"isStopTest":{"type":["boolean","null"],"default":false,"description":"Students cannot go further until they pass this test","example":false},"saveBestResult":{"type":["boolean","null"],"description":"Keep the best result across attempts. Only on a paid tariff of the user.\nAlways `false` when `tries` is `1`; when omitted, `true` for `tries` of 2 or more and `false` for unlimited tries\n","example":true}}},"UpdateTestRequest":{"allOf":[{"$ref":"#\/components\/schemas\/CreateTestRequest"},{"type":"object","required":["isStopTest"],"properties":{"isStopTest":{"type":"boolean","description":"Students cannot go further until they pass this test","example":false}}}]},"Test":{"type":"object","required":["id","userId","status","name","courseId","relatedEntityType","relatedEntityId","order","minimumScoreToSuccess","scorePerQuestion","tries","showAnswers","showExplanations","showAnswersAfterCompletion","startDate","timezone","questions","createdAt","questionCount","description","intervalDate","randomDirection","randomAnswersDirection","questionsLimit","preview","isStopTest","saveBestResult"],"properties":{"id":{"type":"integer","description":"Test identifier","example":5120},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"status":{"type":"string","enum":["blocked","active","inactive","planned","hidden"],"description":"Test status","example":"active"},"name":{"type":"string","description":"Test name","example":"Final test"},"courseId":{"type":"integer","description":"Course identifier","example":12571},"relatedEntityType":{"type":"string","enum":["course","section","lesson"],"description":"Where the test is placed","example":"section"},"relatedEntityId":{"type":"integer","description":"Identifier of the entity the test is placed in","example":8801},"order":{"type":["integer","null"],"description":"Position of the test","example":3},"minimumScoreToSuccess":{"type":["integer","null"],"description":"Minimum score to pass the test","example":0},"scorePerQuestion":{"type":"integer","description":"Score for each correctly answered question","example":1},"tries":{"type":"integer","description":"Number of attempts, `0` for unlimited","example":3},"showAnswers":{"type":"boolean","example":true},"showExplanations":{"type":"boolean","example":false},"showAnswersAfterCompletion":{"type":"boolean","example":false},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date, UTC","example":null},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`","example":null},"questions":{"type":"array","description":"Not filled by create and update operations, always empty","items":{"$ref":"#\/components\/schemas\/TestQuestion"}},"createdAt":{"type":["string","null"],"format":"date-time","description":"Creation time, UTC","example":"2026-02-10T08:30:00.000000Z"},"studentTest":{"type":"null","description":"Not used for this operation, always `null`"},"questionCount":{"type":"integer","description":"Number of questions of the test","example":0},"description":{"type":["string","null"],"description":"Test description","example":"Check what you have learned"},"intervalDate":{"type":["integer","null"],"description":"Delay of the opening, set by the course constructor","example":null},"randomDirection":{"type":"boolean","example":false},"randomAnswersDirection":{"type":"boolean","example":false},"questionsLimit":{"type":["integer","null"],"description":"Number of questions shown to the student","example":null},"preview":{"type":["string","null"],"description":"Preview text","example":null},"isStopTest":{"type":"boolean","example":false},"saveBestResult":{"type":"boolean","example":true},"availableOnTariffs":{"type":["array","null"],"description":"Not filled by this operation, always `null`","items":[],"example":null}}},"SaveTestQuestionsRequest":{"type":"object","properties":{"questions":{"type":"array","minItems":1,"maxItems":300,"description":"The full list of questions of the test, in display order (at most 300 items).\nIf the field is omitted, all existing questions of the test are deleted\n","items":{"$ref":"#\/components\/schemas\/TestQuestionInput"}}}},"TestQuestionInput":{"type":"object","required":["isMultiple","content","variants"],"description":"Either `id` (an existing question of the test to update) or `tmpId` (a new question) must be set. If `tmpId` is set, a new question is created even when `id` is set","properties":{"id":{"type":["integer","null"],"description":"Identifier of an existing question of the test","example":40211},"tmpId":{"type":["string","null"],"description":"Client-side key of a new question","example":"new-1"},"tempId":{"type":["integer","null"],"description":"Client-side number returned in the response as is","example":1},"isMultiple":{"type":"boolean","description":"Several variants can be selected","example":false},"content":{"type":"array","description":"Question content blocks, stored as is","items":{"type":"object","additionalProperties":true},"example":[{"type":"text","value":"What does `len(\"abc\")` return?"}]},"variants":{"type":"array","description":"Answer variants. They are numbered from `0` in the order they are sent","items":{"$ref":"#\/components\/schemas\/TestAnswerVariantInput"}}}},"TestAnswerVariantInput":{"type":"object","required":["isCorrect","text"],"properties":{"text":{"type":"string","description":"Variant text","example":"3"},"isCorrect":{"type":"boolean","description":"The variant is a correct answer","example":true},"contentType":{"type":["string","null"],"enum":["text","image","video","audio",null],"default":"text","description":"Type of the variant. Media types are available only on a paid tariff of the user","example":"text"},"mediaPath":{"type":["string","null"],"description":"Media file path. Prohibited for the `text` type","example":null},"mediaRound":{"description":"Media display option of the editor, stored as is","example":null},"mediaWidth":{"description":"Media display option of the editor, stored as is","example":null},"mediaPosition":{"description":"Media display option of the editor, stored as is","example":null},"explanation":{"type":["string","null"],"maxLength":800,"description":"Explanation shown with the answers","example":"The string has three characters"},"explanationFiles":{"type":["array","null"],"description":"Files attached to the explanation","items":[],"example":null}}},"TestQuestion":{"type":"object","required":["id","tempId","tmpId","userId","testId","status","content","isMultiple","variants","order"],"properties":{"id":{"type":"integer","description":"Question identifier","example":40211},"tempId":{"type":["integer","null"],"description":"`tempId` from the request; `0` when it was not sent","example":1},"tmpId":{"type":["string","null"],"description":"Always `null` in the response","example":null},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"testId":{"type":"integer","description":"Test identifier","example":5120},"status":{"type":"string","enum":["blocked","active"],"description":"Question status","example":"active"},"content":{"type":"array","description":"Question content blocks","items":{"type":"object","additionalProperties":true}},"isMultiple":{"type":"boolean","example":false},"variants":{"type":"array","items":{"$ref":"#\/components\/schemas\/TestAnswerVariant"}},"order":{"type":"integer","description":"Always `0` in the response; the saved order is the position in the request","example":0}}},"TestAnswerVariant":{"type":"object","required":["number","contentType","mediaPath","mediaRound","mediaWidth","mediaPosition","text","isCorrect","explanation","explanationFiles"],"properties":{"number":{"type":"integer","description":"Variant number, starting from `0`","example":0},"contentType":{"type":"string","enum":["text","image","video","audio"],"example":"text"},"mediaPath":{"type":["string","null"],"example":null},"mediaRound":{"example":null},"mediaWidth":{"example":null},"mediaPosition":{"example":null},"text":{"type":["string","null"],"example":"3"},"isCorrect":{"type":"boolean","example":true},"explanation":{"type":["string","null"],"example":"The string has three characters"},"explanationFiles":{"type":["array","null"],"items":[],"example":null}}},"SaveFormRequest":{"type":"object","required":["sectionId","order","status","isStopForm","showAllQuestions","name"],"properties":{"sectionId":{"type":"integer","description":"Section of the course to put the form in. Must be a JSON integer","example":8801},"order":{"type":"integer","description":"Position of the form in the section. Must be a JSON integer","example":2},"status":{"type":"string","enum":["inactive","active","planned","hidden"],"description":"Form status","example":"active"},"isStopForm":{"type":"boolean","description":"Students cannot go further until they submit this form","example":false},"showAllQuestions":{"type":"boolean","description":"Show all questions on one page","example":true},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date. Required when `timezone` is set; must not be in the past","example":null},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`. Only on a paid tariff of the user","example":null},"name":{"type":"string","maxLength":255,"description":"Form name","example":"Feedback form"},"description":{"type":["string","null"],"maxLength":5000,"description":"Form description","example":"Tell us about your experience"}}},"FormResponse":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#\/components\/schemas\/Form"}}},"Form":{"type":"object","required":["id","userId","courseId","sectionId","order","status","isStopForm","showAllQuestions","startDate","timezone","name","description","questions"],"properties":{"id":{"type":"integer","description":"Form identifier","example":2210},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"courseId":{"type":"integer","description":"Course identifier","example":12571},"sectionId":{"type":"integer","description":"Section identifier","example":8801},"order":{"type":"integer","description":"Position of the form in the section","example":2},"status":{"type":"string","enum":["inactive","active","planned","hidden"],"description":"Form status","example":"active"},"isStopForm":{"type":"boolean","example":false},"showAllQuestions":{"type":"boolean","example":true},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date, UTC","example":null},"timezone":{"type":["string","null"],"example":null},"name":{"type":["string","null"],"description":"Form name","example":"Feedback form"},"description":{"type":["string","null"],"description":"Form description","example":"Tell us about your experience"},"questions":{"type":"array","description":"Questions of the form","items":{"$ref":"#\/components\/schemas\/FormQuestion"}},"answer":{"type":"null","description":"Not used for this operation, always `null`"},"availableOnTariffs":{"type":["array","null"],"description":"Not filled by this operation, always `null`","items":[],"example":null}}},"SaveFormQuestionsRequest":{"type":"object","required":["questions"],"properties":{"questions":{"type":"array","minItems":1,"description":"The full list of questions of the form","items":{"$ref":"#\/components\/schemas\/FormQuestionInput"}}}},"FormQuestionInput":{"type":"object","required":["content","required","isMultiple","order","answerType","saveToCrm"],"properties":{"id":{"type":["integer","null"],"description":"Identifier of an existing question of the form to update; omit to create a new question","example":6610},"content":{"type":"array","description":"Question content blocks, stored as is","items":{"type":"object","additionalProperties":true},"example":[{"type":"text","value":"How did you hear about the course?"}]},"required":{"type":"boolean","description":"The student must answer the question","example":true},"isMultiple":{"type":"boolean","description":"Several variants can be selected","example":false},"order":{"type":"integer","description":"Position of the question","example":0},"answerType":{"type":"string","enum":["variant","text","date","file","rate"],"description":"Answer type. Cannot be changed for a question that already has student answers","example":"variant"},"variants":{"type":"array","description":"Answer variants. Required for the `variant` answer type","items":{"$ref":"#\/components\/schemas\/FormQuestionVariant"}},"saveToCrm":{"type":"boolean","description":"Save the answer to a CRM contact field","example":false},"crmField":{"type":["object","null"],"description":"CRM contact field. Required when `saveToCrm` is `true`","required":["id","name"],"properties":{"id":{"type":"integer","description":"CRM field identifier","example":104},"name":{"type":"string","maxLength":255,"description":"CRM field name","example":"Source"}}}}},"FormQuestionVariant":{"type":"object","required":["text"],"properties":{"text":{"type":"string","description":"Variant text","example":"Social networks"},"explanation":{"type":["string","null"],"maxLength":800,"description":"Explanation of the variant","example":null},"explanationFiles":{"type":["array","null"],"description":"Files attached to the explanation","items":[],"example":null}}},"FormQuestionList":{"type":"object","required":["questions"],"properties":{"questions":{"type":"array","items":{"$ref":"#\/components\/schemas\/FormQuestion"}}}},"FormQuestion":{"type":"object","required":["id","formId","content","variants","isMultiple","required","order","answerType","saveToCrm","crmField","hasAnswer"],"properties":{"id":{"type":"integer","description":"Question identifier","example":6610},"formId":{"type":"integer","description":"Form identifier","example":2210},"content":{"type":"array","items":{"type":"object","additionalProperties":true}},"variants":{"type":"array","items":{"$ref":"#\/components\/schemas\/FormQuestionVariant"}},"isMultiple":{"type":"boolean","example":false},"required":{"type":"boolean","example":true},"order":{"type":"integer","example":0},"answerType":{"type":"string","enum":["variant","text","date","file","rate"],"example":"variant"},"saveToCrm":{"type":"boolean","example":false},"crmField":{"type":["object","null"],"description":"CRM contact field","example":null},"hasAnswer":{"type":"boolean","description":"Not filled by this operation, always `false`","example":false}}},"CreateCertificateSectionRequest":{"type":"object","required":["courseId","sectionId","order","name","content","status"],"description":"Either `certificateId` or `certificatePath` must be set.","properties":{"courseId":{"type":"integer","description":"Course identifier. Required in the body and must equal `{courseId}` of the path.\nMust be a JSON integer; the course must belong to the user\n","example":12571},"sectionId":{"type":"integer","description":"Section of the course to put the certificate section in. Must be a JSON integer","example":8801},"certificateId":{"type":["integer","null"],"description":"Certificate template of the user. Required if `certificatePath` is not set","example":912},"certificatePath":{"type":["string","null"],"description":"Path of an uploaded certificate file. Required if `certificateId` is not set","example":null},"order":{"type":"integer","description":"Position in the section. Must be a JSON integer","example":5},"name":{"type":"string","maxLength":255,"description":"Name of the certificate section","example":"Course certificate"},"content":{"type":"array","description":"Content blocks, stored as is","items":{"type":"object","additionalProperties":true},"example":[]},"status":{"type":"string","enum":["inactive","active","planned","hidden"],"description":"Status of the certificate section","example":"active"},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date. Required when `timezone` is set; must not be in the past","example":null},"timezone":{"type":["string","null"],"description":"Timezone of `startDate`","example":null}}},"UpdateCertificateSectionRequest":{"allOf":[{"$ref":"#\/components\/schemas\/CreateCertificateSectionRequest"},{"type":"object","required":["id"],"properties":{"id":{"type":"integer","description":"Identifier of the certificate section to update. Must belong to the user and to the course of the path","example":1305}}}]},"CertificateSectionResponse":{"type":"object","required":["data"],"properties":{"data":{"$ref":"#\/components\/schemas\/CertificateSection"}}},"CertificateSection":{"type":"object","required":["id","userId","courseId","sectionId","certificateId","certificatePath","order","status","name","content","startDate","timezone","uuid","isAchieved","isFavorite","availableOnTariffs"],"properties":{"id":{"type":"integer","description":"Certificate section identifier","example":1305},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"courseId":{"type":"integer","description":"Course identifier","example":12571},"sectionId":{"type":"integer","description":"Section identifier","example":8801},"certificateId":{"type":["integer","null"],"description":"Certificate template identifier","example":912},"certificatePath":{"type":["string","null"],"description":"Path of the certificate file","example":null},"order":{"type":"integer","example":5},"status":{"type":"string","enum":["inactive","active","planned","hidden"],"example":"active"},"name":{"type":"string","example":"Course certificate"},"content":{"type":"array","items":{"type":"object","additionalProperties":true}},"startDate":{"type":["string","null"],"format":"date-time","description":"Opening date, UTC","example":null},"timezone":{"type":["string","null"],"example":null},"uuid":{"type":["string","null"],"description":"Not filled by this operation","example":null},"isAchieved":{"type":"boolean","description":"Not filled by this operation, always `false`","example":false},"isFavorite":{"type":["boolean","null"],"description":"Not filled by this operation","example":false},"availableOnTariffs":{"type":["array","null"],"description":"Not filled by this operation, always `null`","items":[],"example":null}}},"CreateSchoolRequest":{"type":"object","required":["name","systemDomainId","domainName","isLms"],"properties":{"name":{"type":"string","minLength":3,"maxLength":255,"description":"School name","example":"Coding school"},"studentsName":{"type":["string","null"],"minLength":3,"maxLength":255,"description":"Custom name for students. Defaults to `name`","example":"Pupils"},"systemDomainId":{"type":"integer","minimum":1,"description":"System domain to create the school subdomain on (`systemDomainId` from `listSystemDomains`). Must be a JSON integer","example":1},"domainName":{"type":"string","maxLength":64,"description":"Subdomain of the school site. Must be free (see `checkSubdomainName`)","example":"coding-school"},"isLms":{"type":"boolean","description":"Create an LMS school","example":false},"templateId":{"type":["integer","null"],"description":"Site template identifier","example":null}}},"UpdateSchoolRequest":{"type":"object","required":["name"],"properties":{"name":{"type":"string","minLength":3,"maxLength":255,"description":"School name","example":"Coding school"},"studentsName":{"type":["string","null"],"minLength":3,"maxLength":255,"description":"Custom name for students. Omitted or `null` clears it","example":"Pupils"},"isLms":{"type":["boolean","null"],"description":"Only `true` is applied; `false` or `null` leaves the LMS flag unchanged","example":null},"status":{"type":["string","null"],"enum":["inactive","active","deleted",null],"default":"inactive","description":"School status. Omitted or `null` sets `inactive`","example":"active"}}},"ReorderSchoolsRequest":{"type":"object","required":["order"],"properties":{"order":{"type":"array","description":"Positions of all schools of the user","items":{"type":"object","required":["id","position"],"properties":{"id":{"type":"integer","description":"School identifier. Must be a JSON integer; the school must belong to the user","example":3307},"position":{"type":"integer","description":"New position of the school. Positions must be unique. Must be a JSON integer","example":1}}}}}},"SchoolDetails":{"description":"School with the number of its courses","allOf":[{"$ref":"#\/components\/schemas\/School"},{"type":"object","required":["coursesCount","gamificationEnabled"],"properties":{"coursesCount":{"type":["integer","null"],"description":"Number of courses of the school that are not deleted","example":0},"gamificationEnabled":{"type":"boolean","description":"Gamification is enabled in the student cabinet of the school","example":false}}}]},"Domain":{"type":"object","required":["id","status","name","subdomain","systemDomainId"],"properties":{"id":{"type":"integer","description":"Domain identifier (`domainId` of schools and courses)","example":2201},"status":{"type":"string","enum":["new","approved","notActive","deleted"],"description":"Domain status","example":"approved"},"name":{"type":"string","description":"Full domain name","example":"coding-school.sendpulse.online"},"subdomain":{"type":["string","null"],"description":"Subdomain part, `null` for a custom domain","example":"coding-school"},"systemDomainId":{"type":["integer","null"],"description":"System domain of the subdomain, `null` for a custom domain","example":1}}},"SystemDomain":{"type":"object","required":["systemDomainId","name"],"properties":{"systemDomainId":{"type":"integer","description":"System domain identifier","example":1},"name":{"type":"string","description":"System domain name","example":"sendpulse.online"}}},"SubdomainAvailability":{"type":"object","required":["isSubdomainFree"],"properties":{"isSubdomainFree":{"type":"boolean","description":"The subdomain is free","example":true}}},"CreateHomeworkRequest":{"type":"object","required":["name","autoAccept","courseId","lessonId","content"],"properties":{"name":{"type":"string","description":"Homework task name","example":"Write a function"},"autoAccept":{"type":"boolean","description":"Accept submitted homeworks automatically after `autoAcceptTime`","example":true},"autoAcceptTime":{"type":"integer","description":"Delay of the automatic acceptance in seconds. Required when `autoAccept` is `true`. Must be a JSON integer","example":86400},"courseId":{"type":"integer","description":"Course identifier. Must be a JSON integer; the course must belong to the user","example":12571},"lessonId":{"type":"integer","description":"Lesson of the course to attach the task to. Must be a JSON integer","example":90211},"content":{"type":"array","description":"Task content blocks, stored as is","items":{"type":"object","additionalProperties":true},"example":[{"type":"text","value":"Write a function that reverses a string."}]},"filesPaths":{"type":"array","description":"Paths of files attached to the task","items":{"type":"string"},"example":[]},"attachmentsRequired":{"type":["boolean","null"],"default":false,"description":"The student must attach a file to the answer","example":false},"disablePaste":{"type":["boolean","null"],"default":false,"description":"Forbid pasting text into the answer","example":false},"isOptional":{"type":["boolean","null"],"default":false,"description":"The homework is optional for completing the lesson","example":false}}},"UpdateHomeworkRequest":{"type":"object","required":["name","autoAccept","courseId","content"],"properties":{"name":{"type":"string","description":"Homework task name","example":"Write a function"},"autoAccept":{"type":"boolean","description":"Accept submitted homeworks automatically after `autoAcceptTime`","example":true},"autoAcceptTime":{"type":"integer","description":"Delay of the automatic acceptance in seconds. Required when `autoAccept` is `true`. Must be a JSON integer","example":86400},"courseId":{"type":"integer","description":"Required and must be a course of the user, but not used \u2014 the task stays in its course","example":12571},"content":{"type":"array","description":"Task content blocks, stored as is","items":{"type":"object","additionalProperties":true},"example":[{"type":"text","value":"Write a function that reverses a string."}]},"filesPaths":{"type":"array","description":"Paths of files attached to the task","items":{"type":"string"},"example":[]},"attachmentsRequired":{"type":["boolean","null"],"default":false,"description":"The student must attach a file to the answer","example":false},"disablePaste":{"type":["boolean","null"],"default":false,"description":"Forbid pasting text into the answer","example":false},"isOptional":{"type":["boolean","null"],"default":false,"description":"The homework is optional for completing the lesson","example":false}}},"HomeworkTaskDetails":{"type":"object","required":["id","name","userId","autoAccept","autoAcceptTime","lessonId","courseId","schoolId","content","filesPaths","homeworkStudent","lessonName","attachmentsRequired","disablePaste","isOptional"],"properties":{"id":{"type":"integer","description":"Homework task identifier","example":7731},"name":{"type":"string","description":"Homework task name","example":"Write a function"},"userId":{"type":"integer","description":"Owner user identifier","example":8812345},"autoAccept":{"type":"boolean","example":true},"autoAcceptTime":{"type":["integer","null"],"description":"Delay of the automatic acceptance in seconds","example":86400},"lessonId":{"type":["integer","null"],"description":"Lesson identifier","example":90211},"courseId":{"type":["integer","null"],"description":"Course identifier","example":12571},"schoolId":{"type":["integer","null"],"description":"School identifier","example":null},"content":{"type":"array","items":{"type":"object","additionalProperties":true}},"filesPaths":{"type":["array","null"],"items":{"type":"string"},"example":[]},"homeworkStudent":{"type":"null","description":"Not used for this operation, always `null`"},"lessonName":{"type":["string","null"],"description":"Name of the lesson the task is attached to","example":"Variables"},"attachmentsRequired":{"type":"boolean","example":false},"disablePaste":{"type":"boolean","example":false},"isOptional":{"type":"boolean","example":false}}}},"responses":{"Unauthorized":{"description":"The access token has expired or its signature is invalid, or no user is resolved from it","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"},"examples":{"expiredToken":{"value":{"success":false,"error":{"code":401,"message":"Expired token"}}},"unknownUser":{"value":{"success":false,"error":{"code":401,"message":"Unauthorized action!"}}}}}}},"Forbidden":{"description":"Returned in one of two shapes:\n- `ErrorResponse` \u2014 the Authorization header is missing, the token cannot be decoded, or Public API is not available for the user's tariff;\n- `ErrorList` \u2014 the requested entity does not belong to the user.\n","content":{"application\/json":{"schema":{"oneOf":[{"$ref":"#\/components\/schemas\/ErrorResponse"},{"$ref":"#\/components\/schemas\/ErrorList"}]},"examples":{"missingToken":{"value":{"success":false,"error":{"code":403,"message":"Unauthorized action!"}}},"tariffRestriction":{"value":{"success":false,"error":{"code":403,"message":"Public API is not available for the current tariff"}}},"notOwned":{"value":{"errors":[{"code":403,"message":"Forbidden"}]}}}}}},"NotFound":{"description":"Entity not found, or a path parameter has an invalid format","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"},"example":{"success":false,"error":{"code":404,"message":"Not found"}}}}},"ValidationFailed":{"description":"Request validation failed","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ValidationError"}}}},"TooManyRequests":{"description":"More than 100 requests per minute. The response has no `Retry-After` or `X-RateLimit-*` headers; retry in a minute.\n","content":{"application\/json":{"schema":{"$ref":"#\/components\/schemas\/ErrorResponse"},"example":{"success":false,"error":{"code":429,"message":"Too Many Attempts."}}}}}},"securitySchemes":{"oauth2":{"type":"oauth2","flows":{"clientCredentials":{"tokenUrl":"https:\/\/api.sendpulse.com\/oauth\/access_token","scopes":[]}}},"apiKey":{"type":"apiKey","in":"header","name":"Authorization"}}},"security":[{"oauth2":[]},{"apiKey":[]}]}