openapi: 3.1.1
info:
  version: '6.0'
  title: Open Education API
  description: |
    OpenAPI (fka Swagger) specification for the Open Education API. 

    The model provides an overview of the educational domain that is modelled and
    forms the basis of the OOAPI. The overarching educational concept is not exposed
    through API endpoints. Instead, the educational specification defines four base
    objects: programme, course, learning component, and test component, each with
    its own endpoint.

    These base objects can be used to realise offerings. There is, however, no
    dedicated offering endpoint. Offerings are represented through four base
    types: programme offering, course offering, learning component offering, and
    test component offering.

    Relations between an offering and a person, such as enrolment, are realised
    through association endpoints. These endpoints define the different types of
    associations that can exist between offerings and persons. Other objects shown
    in the model represent groups and group memberships of a person.
  contact:
    name: OOAPI Working Group / SURF
    url: https://openonderwijsapi.nl
    email: info@openonderwijsapi.nl
  x-logo:
    url: ./logo.png
    href: ./docs.html
servers:
  - url: http://demo01.eduapi.nl/v6
    description: SURF demo implementation
security: []
tags:
  - name: academic sessions
    description: |
      The academic sessions API provides information about the different time periods
      a programme can be offered.
  - name: academic_session_model
    x-displayName: AcademicSession
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/AcademicSession" />
  - name: associations
    x-deprecated: true
    description: |
      The association API is now deprecated and has been replaced by more specific
      endpoints programme-offering-association, course-offering-association, 
      learning-component-offering-association and test-component-offering-association.
  - name: building_model
    x-displayName: Building
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Building" />
  - name: buildings
    description: |
      The building API provides a building that is currently used by the organisation.
      It includes all location details.
  - name: components
    description: |
      This path is no longer supported; you can now use learning components or test
      components.
  - name: course offering associations
    description: |
      The course offering associations API provides information about the association
      between a course offering and a person (e.g. students, lecturers, etc).
      Associations can be posted between institutions. This requires detailed information
      on the course offering and the persons. To allow for this information a
      complete person object and offering object can be part of the API. The structure
      is explained in the following model:
      <table>
        <tr>
         <td></td>
         <td colspan=3 align=center>offering</td>
        </tr>
        <tr>
         <td rowspan=3>student</td>
         <td></td>
         <!-- <td>internal</td>
         -->
         <td>external</td>
        </tr>
        <tr>
         <td>internal</td>
         <td>POST <a
           href="#tag/course-offering-associations/operation/createExternalCourseOfferingAssociationByopenId">
           /course-offering-associations/external/me</a>Retrieves student details from the well known endpoint 
           that exposes person information at the home institution.
           It passes offering details (provided by
           external institution) to the home institution so the home institution can
           create a placeholder for the offering and its results.
         </td>
        </tr>
        <tr>
         <td>external</td>
         <td>no support needed</td>
        </tr>
      </table>
      Direct update of current information: <a
        href="#tag/course-offering-associations/operation/partialUpdateCourseOfferingAssociationById">
        PATCH /course-offering-associations/{courseOfferingAssociationId}</a>
      This call is currently limited to passing results and a remote state. For future
      use other association resource information could be passed. More information on
      the support for student mobility can be found
      <a href="https://swimlanes.io/d/s5mfpj7Si">here</a>
  - name: course offerings
    description: |
      The offerings API provides information about offerings which have a global
      timeframe, e.g. a period to which students can enrol.
  - name: course_model
    x-displayName: Course
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Course" />
  - name: course_offering_association_model
    x-displayName: CourseOfferingAssociation
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/CourseOfferingAssociation" />
  - name: course_offering_model
    x-displayName: CourseOffering
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/CourseOffering" />
  - name: courses
    description: |
      The courses API provides a self-contained and formally structured learning experience,
      aimed at delivering defined learning outcomes to students, usually within the context
      of a programme.
  - name: data_model
    x-displayName: Data model
    description: |
      The Open Education API defines different objects using schemas.
      These schemas are based on OpenAPI base types, with occasional specific amendments to these base types.
      The types we use are:
        The data type of a schema is defined by the type keyword, for example, type: string. OpenAPI defines the following basic types:
        - [string](#strings) (this includes dates and files)
        - number
        - integer
        - boolean
        - array
        - [object](#objects)


      ### Strings

      A string of text is defined as:

      ```yaml  
      type: string
      String length can be restricted using minLength and maxLength:
      ```


      ```yaml
        type: string
        minLength: 3
        maxLength: 20
      ```

      Note that an empty string "" is a valid string unless minLength or pattern is specified.
      String Formats

      An optional format modifier can be used as a hint about the contents and structure of the string. OpenAPI defines the following built-in string formats:


      ```yaml  
      date – full-date notation as defined by RFC 3339, section 5.6, for example, 2017-07-21
      date-time – the date-time notation as defined by RFC 3339, section 5.6, for example, 2017-07-21T17:32:28+1:00
      byte – base64-encoded characters, for example, U3dhZ2dlciByb2Nrcw==
      binary – binary data, used to describe files
      ```

      ### Objects

      The Open Education API contains a set of predefined objects that are related to one another. 
      All objects listed below, and the relations between them are shown in the model at the top of this page. 
  - name: document_model
    x-displayName: Document
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Document" />
  - name: documents
    description: The API for accessing and retrieving document resources.
  - name: group_model
    x-displayName: Group
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Group" />
  - name: groups
    description: |
      The groups API provides information about groups that are related to
      organisations, persons and offerings. Groups of students that are related to an
      offering are typically used for rostering. The rostering application assigns
      students based on these groups. For example, class 1b will be assigned to the
      course offering on Monday morning. Not all groups are related to an offering. A
      group of people can also be a team that is working on a task outside the 
      scope of the OOAPI. These can be teams of students, but also teams of employees.
  - name: learning component offering associations
    description: |
      The API for associations between persons and learning component offerings.
  - name: learning component offerings
    description: |
      The offerings API provides information about offerings which have a global
      timeframe, e.g. a period to which students can enrol.
  - name: learning components
    description: |
      The learning components API provides information about learning activities that
      are part of a course (or learning component).
  - name: learning outcomes
    description: |
      The learning outcomes API provides information about the statements regarding
      what a learner knows, understands and is able to do on completion of a learning
      process, which are defined in terms of knowledge, skills and responsibility and
      autonomy.
  - name: learning_component_model
    x-displayName: LearningComponent
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/LearningComponent" />
  - name: learning_component_offering_association_model
    x-displayName: LearningComponentOfferingAssociation
    description: |
      <SchemaDefinition
        schemaRef="#/components/schemas/LearningComponentOfferingAssociation" />
  - name: learning_component_offering_model
    x-displayName: LearningComponentOffering
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/LearningComponentOffering" />
  - name: learning_outcome_model
    x-displayName: LearningOutcome
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/LearningOutcome" />
  - name: membership_model
    x-displayName: Membership
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Membership" />
  - name: memberships
    description: |
      The memberships API provides information about memberships that are related to
      groups and persons. 
  - name: news
    description: This path is no longer supported.
  - name: organisation_model
    x-displayName: Organisation
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Organisation" />
  - name: organisations
    description: |
      The organisations API provides the organisations that are responsible for the
      execution and recognition of education, either as an educational institution or
      as an organisation providing services, internships or facilities.
  - name: person_model
    x-displayName: Person
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Person" />
  - name: persons
    description: |
      The persons API provides information about persons related to an organisation.
  - name: programme offering associations
    description: |
      The programme offering associations API provides information about the association
      between a programme offering and a person (e.g. students, lecturers, etc).
      Associations can be posted between institutions. This requires detailed information
      on the programme offering and the persons. To allow for this information a
      complete person object and offering object can be part of the API. The structure
      is explained in the following model:
      <table>
        <tr>
         <td></td>
         <td colspan=3 align=center>offering</td>
        </tr>
        <tr>
         <td rowspan=3>student</td>
         <td></td>
         <!-- <td>internal</td>
         -->
         <td>external</td>
        </tr>
        <tr>
         <td>internal</td>
         <!-- <td>POST <a
              href="#tag/offerings/paths/~1offerings~1{offeringId}~1associations~1external/post">
              /offerings/{offeringId}/associations/me</a> local enrolment based on
              selected offering
              This call will allow for a local student using his well known credentials
              to enrol for the offering identified by the offeringId
              <br>Alternatively the association can also be created through POST
              <a href="#tag/associations/paths/~1associations~1me/post">/associations/me</a>
             </td>
         -->
         <td>POST <a
           href="#tag/course-offering-associations/operation/createExternalProgrammeOfferingAssociationByopenId">
           /programme-offering-associations/external/me</a>Retrieves student details from the well known endpoint 
           that exposes person information at the home institution.
           It passes offering details (provided by
           external institution) to the home institution so the home institution can
           create a placeholder for the offering and its results.
         </td>
        </tr>
        <tr>
         <td>external</td>
          <!--
          <td>
          This method is not yet implemented it requires full student details and
          offering details. This would mean the OOAPI message would contain more than
          one resource in the message. At the moment the student mobility project is
          looking into a solution.
          <br> Alternatively it could be achieved through using two calls:
          <ul>
           <li>create student with POST
               <a href="#tag/persons/paths/~1persons~1{personId}/post">/persons</a>
           </li>
           <li>
               <a href="#tag/offerings/paths/~1offerings~1{offeringId}~1associations~1external/post">
               /offerings/{offeringId}/associations/me</a>
           </li>
          </ul>
          for the enrolment
         </td>
          -->
         <td>no support needed</td>
        </tr>
      </table>
      Direct update of current information: <a
        href="#tag/programme-offering-associations/operation/partialUpdateProgrammeOfferingAssociationById">
        PATCH /programme-offering-associations/{programmeOfferingAssociationId}</a>
      This call is currently limited to passing results and a remote state. For future
      use other association resource information could be passed. More information on
      the support for student mobility can be found
      <a href="https://swimlanes.io/d/s5mfpj7Si">here</a>
  - name: programme offerings
    description: |
      The offerings API provides information about offerings which have a global
      timeframe, e.g. a period to which students can enrol.
  - name: programme_model
    x-displayName: Programme
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Programme" />
  - name: programme_offering_association_model
    x-displayName: ProgrammeOfferingAssociation
    description: |
      <SchemaDefinition
        schemaRef="#/components/schemas/ProgrammeOfferingAssociation" />
  - name: programme_offering_model
    x-displayName: ProgrammeOffering
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/ProgrammeOffering" />
  - name: programmes
    description: |
      The programmes API provides a coherent set of educational components, aimed at the
      realisation of competences or objectives in the field of knowledge, insight,
      attitudes and skills that the person who completes the programme must have.
  - name: room_model
    x-displayName: Room
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Room" />
  - name: rooms
    description: |
      The rooms API provides the part of a building where an activity can take place.
      Including detailed information on the resources available, number of seats, etc.
      (Updated continuously)
  - name: security
    description: |
      Within the specification, no global security is defined. This keeps the core
      specification neutral and avoids prescribing a single security model for all
      operations. For those API calls that require authentication or authorisation,
      this is explicitly indicated in the accompanying documentation.

      By leaving the global security section empty, implementation details are
      separated from the functional description, while still providing guidance on how
      concrete security measures can be applied in practice.
  - name: service metadata
    description: |
      The service API provides additional metadata needed to make the OOAPI fit for
      this organisation.
  - name: service_model
    x-displayName: Service
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/Service" />
  - name: test component offering association attempts
    description: The API for the attempts that are made by a person on a test component offering association.
  - name: test component offering associations
    description: |
      The API for associations between persons and test component offerings.
  - name: test component offerings
    description: |
      The offerings API provides information about offerings which have a global
      timeframe, e.g. a period to which students can enrol.
  - name: test components
    description: |
      The test components API provides information about test or assessment activities
      that are part of a course (or learning unit).
  - name: test_component_model
    x-displayName: TestComponent
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/TestComponent" />
  - name: test_component_offering_association_attempt_model
    x-displayName: TestComponentOfferingAssociationAttempt
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/TestComponentOfferingAssociationAttemptFull" />
  - name: test_component_offering_association_model
    x-displayName: TestComponentOfferingAssocation
    description: |
      <SchemaDefinition
        schemaRef="#/components/schemas/TestComponentOfferingAssociation" />
  - name: test_component_offering_model
    x-displayName: TestComponentOffering
    description: |
      <SchemaDefinition schemaRef="#/components/schemas/TestComponentOffering" />
paths:
  /:
    get:
      parameters: []
      summary: GET /
      operationId: listServiceMetaData
      description: Get metadata for the service.
      tags:
        - service metadata
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Service'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /academic-sessions:
    get:
      summary: GET /academic-sessions
      operationId: listAcademicSessions
      description: Get a list of all academic sessions, ordered chronologically.
      tags:
        - academic sessions
      parameters:
        - $ref: '#/components/parameters/primaryCode'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - name: academicSessionType
          in: query
          description: Filter by academic session type
          required: false
          schema:
            $ref: '#/components/schemas/academicSessionType'
        - name: parent
          in: query
          description: Filter by parent (academicSessionId)
          required: false
          schema:
            type: string
            format: uuid
        - name: year
          in: query
          description: Filter by year (academicSessionId)
          required: false
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/AcademicSession'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /academic-sessions/{academicSessionId}:
    get:
      summary: GET /academic-sessions/{academicSessionId}
      operationId: listAcademicSessionById
      description: Get a single academic session.
      tags:
        - academic sessions
      parameters:
        - name: academicSessionId
          in: path
          description: Academic session ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - parent
                - children
                - year
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/AcademicSession'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /academic-sessions/{academicSessionId}/course-offerings:
    get:
      summary: GET /academic-sessions/{academicSessionId}/course-offerings
      operationId: listCourseOfferingsByAcademicSessionId
      description: Get a list of all course offerings during this academic session
      tags:
        - course offerings
      parameters:
        - name: academicSessionId
          in: path
          description: Academic session ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        $ref: '#/components/schemas/CourseOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /academic-sessions/{academicSessionId}/learning-component-offerings:
    get:
      summary: GET /academic-sessions/{academicSessionId}/learning-component-offerings
      operationId: listLearningComponentOfferingsByAcademicSessionId
      description: Get a list of all offerings during this academic session
      tags:
        - learning component offerings
      parameters:
        - name: academicSessionId
          in: path
          description: Academic session ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /academic-sessions/{academicSessionId}/programme-offerings:
    get:
      summary: GET /academic-sessions/{academicSessionId}/programme-offerings
      operationId: listProgrammeOfferingsByAcademicSessionId
      description: Get a list of all programme offerings during this academic session
      tags:
        - programme offerings
      parameters:
        - name: academicSessionId
          in: path
          description: Academic session ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/ProgrammeOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /academic-sessions/{academicSessionId}/test-component-offerings:
    get:
      summary: GET /academic-sessions/{academicSessionId}/test-component-offerings
      operationId: listTestComponentOfferingsByAcademicSessionId
      description: Get a list of all test component offerings during this academic session
      tags:
        - test component offerings
      parameters:
        - name: academicSessionId
          in: path
          description: Academic session ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /buildings:
    get:
      summary: GET /buildings
      operationId: listBuildings
      description: Get a list of all buildings, ordered by name (ascending).
      tags:
        - buildings
      parameters:
        - $ref: '#/components/parameters/primaryCode'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Building'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /buildings/{buildingId}:
    get:
      summary: GET /buildings/{buildingId}
      operationId: listBuildingById
      description: Get a single building.
      tags:
        - buildings
      parameters:
        - name: buildingId
          in: path
          description: Building ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Building'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /buildings/{buildingId}/rooms:
    get:
      summary: GET /buildings/{buildingId}/rooms
      operationId: listRoomsByBuildingId
      description: Get a list of all rooms in a building.
      tags:
        - buildings
      parameters:
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - name: buildingId
          in: path
          description: The id of the building to find rooms for
          required: true
          schema:
            type: string
            format: uuid
        - name: roomType
          in: query
          description: Filter by room type
          required: false
          schema:
            $ref: '#/components/schemas/roomType'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Room'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /course-offering-associations/external/me:
    post:
      summary: POST /course-offering-associations/external/me
      operationId: createExternalCourseOfferingAssociationByopenId
      description: |
        POST a single course offering association, enrol a person based on person information obtained from well known endpoint, an offering, 
        and the organisation/type=root information from the organisation that is issuing this association. 
        The offering can either be identified by an offeringId if known or the full offering details. 

        Security must be implemented at the level of the actual deployment rather than in the core specification. 
        This means that the specification remains neutral, while concrete security measures can be applied in 
        practice using established techniques such as OpenID with fine-grained scopes. For example, write access 
        on course-offering associations for an external user (me.write) can be granted in this way. The previous 
        inline declaration has therefore been removed to avoid conflating implementation details with the 
        specification.
      tags:
        - course offering associations
      requestBody:
        required: true
        content:
          application/json:
            schema:
              required:
                - remoteState
              allOf:
                - $ref: '#/components/schemas/CourseOfferingAssociationExternalMe'
                - properties:
                    issuer:
                      $ref: '#/components/schemas/Organisation'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/AssociationId'
                  - $ref: '#/components/schemas/PostResponse'
                  - properties:
                      state:
                        $ref: '#/components/schemas/associationState'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /course-offering-associations/{courseOfferingAssociationId}:
    get:
      summary: GET /course-offering-associations/{courseOfferingAssociationId}
      operationId: listCourseOfferingAssociationById
      description: Get a single course offering association.
      tags:
        - course offering associations
      parameters:
        - name: courseOfferingAssociationId
          in: path
          description: Course Offering Association ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - academic_session
                - course_offering
                - person
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseOfferingAssociation'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /course-offering-associations/{courseOfferingAssociationId}
      description: |
        PUT a single course offering association to enrol a person on a specific association that can later be retrieved.  
      operationId: replaceCourseOfferingAssociationById
      tags:
        - course offering associations
      parameters:
        - name: courseOfferingAssociationId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CourseOfferingAssociation'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    patch:
      summary: PATCH /course-offering-associations/{courseOfferingAssociationId}
      operationId: partialUpdateCourseOfferingAssociationById
      description: |
        Update the status or result of an enrolment. Other elements of the association object COULD 
        also be PATCHED. But are not likely and have therefore not been included in this endpoint.
        Implementation of the PATCH activity is based on use PATCH with JSON Merge Patch standard, 
        a specialized media type `application/merge-patch+json` for partial resource representation 
        to update parts of resource objects.

        Security must be implemented at the level of the actual deployment rather than in the core 
        specification. This means that the specification remains neutral, while concrete security 
        measures can be applied in practice using established techniques such as OpenID with fine-grained 
        scopes. For example, write access on associations (associations.write) can be granted in this way. 
        The previous inline declaration has therefore been removed to avoid conflating implementation 
        details with the specification.
      tags:
        - course offering associations
      parameters:
        - name: courseOfferingAssociationId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/merge-patch+json:
            schema:
              properties:
                remoteState:
                  $ref: '#/components/schemas/remoteAssociationState'
                result:
                  $ref: '#/components/schemas/CourseOfferingAssociationResult'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/AssociationId'
                  - $ref: '#/components/schemas/PostResponse'
                  - properties:
                      state:
                        $ref: '#/components/schemas/associationState'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /course-offerings/{courseOfferingId}:
    get:
      summary: GET /course-offerings/{courseOfferingId}
      operationId: listCourseOfferingsById
      description: Get a single course offering.
      tags:
        - course offerings
      parameters:
        - name: courseOfferingId
          in: path
          description: Course Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - course
                - programme_offering
                - academic_session
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseOffering'
                title: courseOffering
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /course-offerings/{courseOfferingId}
      operationId: replaceCourseOfferingsById
      description: Update all attributes of a single course offering.
      tags:
        - course offerings
      parameters:
        - name: courseOfferingId
          in: path
          description: Course Offering ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CourseOffering'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    patch:
      summary: PATCH /course-offerings/{courseOfferingId}
      operationId: partialUpdateCourseOfferingsById
      description: Change attributes of a single course offering.
      tags:
        - course offerings
      parameters:
        - name: courseOfferingId
          in: path
          description: Course Offering ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/CourseOffering'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /course-offerings/{courseOfferingId}/course-offering-associations:
    get:
      summary: GET /course-offerings/{courseOfferingId}/course-offering-associations
      operationId: listCourseOfferingAssociationsByCourseOfferingId
      description: Get a list of all course offering associations related to the course offering based on its ID.
      tags:
        - course offering associations
      parameters:
        - name: courseOfferingId
          in: path
          description: Course Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - name: role
          in: query
          description: Filter by role
          required: false
          schema:
            $ref: '#/components/schemas/associationRole'
        - name: state
          in: query
          description: Filter by state
          required: false
          schema:
            $ref: '#/components/schemas/associationState'
        - name: resultState
          in: query
          description: Filter by result state
          required: false
          schema:
            $ref: '#/components/schemas/resultState'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/CourseOfferingAssociation'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /course-offerings/{courseOfferingId}/groups:
    get:
      summary: GET /course-offerings/{courseOfferingId}/groups
      operationId: listGroupsByCourseOfferingId
      description: Get an ordered list of all groups related to a course offering, ordered by name.
      tags:
        - groups
      parameters:
        - name: courseOfferingId
          in: path
          description: Course Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - name: groupType
          in: query
          description: Filter by group type
          required: false
          schema:
            $ref: '#/components/schemas/groupType'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Group'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /course-offerings/{courseOfferingId}/learning-component-offerings:
    get:
      summary: GET /course-offerings/{courseOfferingId}/learning-component-offerings
      operationId: listLearningComponentOfferingsByCourseOfferingId
      description: Get a list of all learning component offerings related to the course offering based on its ID.
      tags:
        - learning component offerings
      parameters:
        - name: courseOfferingId
          in: path
          description: Course Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (date-time). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (date-time).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /course-offerings/{courseOfferingId}/test-component-offerings:
    get:
      summary: GET /course-offerings/{courseOfferingId}/test-component-offerings
      operationId: listTestComponentOfferingsByCourseOfferingId
      description: Get a list of all test component offerings related to the course offering based on its ID.
      tags:
        - test component offerings
      parameters:
        - name: courseOfferingId
          in: path
          description: Course Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /courses:
    get:
      summary: GET /courses
      operationId: listCourses
      description: Get a list of all courses, ordered by name (ascending).
      tags:
        - courses
      parameters:
        - $ref: '#/components/parameters/primaryCode'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - name: level
          in: query
          description: Filter by level
          required: false
          schema:
            $ref: '#/components/schemas/level'
        - name: modeOfDelivery
          in: query
          description: Filter by modeOfDelivery
          required: false
          schema:
            $ref: '#/components/schemas/modeOfDelivery'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Course'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /courses/{courseId}:
    get:
      summary: GET /courses/{courseId}
      operationId: listCourseById
      description: Get a single course.
      tags:
        - courses
      parameters:
        - name: courseId
          in: path
          description: Course ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to include, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - programmes
                - coordinators
                - instructors
                - organisation
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/returnTimelineOverrides'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/CourseExpanded'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /courses/{courseId}/course-offerings:
    get:
      summary: GET /courses/{courseId}/course-offerings
      operationId: listCourseOfferingsByCourseId
      description: Get a list of all course offerings for this course, ordered chronologically.
      tags:
        - course offerings
      parameters:
        - name: courseId
          in: path
          description: Course ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: modeOfDelivery
          in: query
          description: Filter by modeOfDelivery
          required: false
          schema:
            $ref: '#/components/schemas/modeOfDelivery'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/CourseOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /courses/{courseId}/learning-component-offerings:
    get:
      summary: GET /courses/{courseId}/learning-component-offerings
      operationId: listLearningCompoentOfferingsByCourseId
      description: Get a list of all learning component offerings for this course, ordered chronologically.
      tags:
        - learning component offerings
      parameters:
        - name: courseId
          in: path
          description: Course ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: modeOfDelivery
          in: query
          description: Filter by modeOfDelivery
          required: false
          schema:
            $ref: '#/components/schemas/modeOfDelivery'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
        - name: expand
          in: query
          explode: false
          description: Optional properties to include, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - academic_session
                - course_offering
                - learning_component
                - organisation
                - rooms
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /courses/{courseId}/learning-components:
    get:
      summary: GET /courses/{courseId}/learning-components
      operationId: listLearningComponentsByCourseId
      description: Get an ordered list of all course learning components.
      tags:
        - learning components
      parameters:
        - name: courseId
          in: path
          description: Course ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningComponent'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /courses/{courseId}/test-component-offerings:
    get:
      summary: GET /courses/{courseId}/test-component-offerings
      operationId: listTestCompoentOfferingsByCourseId
      description: Get a list of all test component offerings for this course, ordered chronologically.
      tags:
        - test component offerings
      parameters:
        - name: courseId
          in: path
          description: Course ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: modeOfDelivery
          in: query
          description: Filter by modeOfDelivery
          required: false
          schema:
            $ref: '#/components/schemas/modeOfDelivery'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /courses/{courseId}/test-components:
    get:
      summary: GET /courses/{courseId}/test-components
      operationId: listTestComponentsByCourseId
      description: Get an ordered list of all course test components.
      tags:
        - test components
      parameters:
        - name: courseId
          in: path
          description: Course ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponent'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /documents/{documentId}:
    get:
      summary: GET /documents/{documentId}
      operationId: listDocumentById
      description: |
        Get the binary data from a document.

        Security must be implemented at the level of the actual deployment rather than in the core specification. 
        This means that the specification remains neutral, while concrete security measures can be applied in practice 
        using established techniques such as OAuth flows with fine-grained definitions. For example, access may be 
        managed through the flow identified as nl-test-admin-flow-2-3-4. The previous inline declaration has therefore 
        been removed to avoid conflating implementation details with the specification.
      tags:
        - documents
      parameters:
        - name: documentId
          in: path
          description: Document ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          content:
            application/octet-stream:
              schema:
                type: string
                format: binary
              examples:
                file-download:
                  description: File download
                  summary: File download
                  value: <raw data>
          description: OK
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /groups:
    get:
      summary: GET /groups
      operationId: listGroups
      description: Get a list of all groups, ordered by name (ascending).
      tags:
        - groups
      parameters:
        - $ref: '#/components/parameters/primaryCode'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/search'
        - name: groupType
          in: query
          description: Filter by group type
          required: false
          schema:
            $ref: '#/components/schemas/groupType'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Group'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /groups/{groupId}:
    get:
      summary: GET /groups/{groupId}
      operationId: listGroupById
      description: Get a single group.
      tags:
        - groups
      parameters:
        - name: groupId
          in: path
          description: Group ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - organisation
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Group'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /groups/{groupId}
      operationId: replaceGroupById
      description: Replace a single group from source system to recipient.
      tags:
        - groups
      parameters:
        - name: groupId
          in: path
          description: Group ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Group'
              title: group
            examples:
              Create a group in remote system:
                value:
                  groupId: 123e4567-e89b-12d3-a456-426614174000
                  offeringIds:
                    - courseOfferingId: 123e4567-e89b-12d3-a456-426614174000
                    - programmeOfferingId: 223e4567-e89b-12d3-a456-426614174000
                  primaryCode:
                    codeType: identifier
                    code: 1234qwe12
                  groupType: learning group
                  name:
                    - language: en-GB
                      value: statistics students
                  description:
                    - language: en-GB
                      value: The group of students that follow statistics classes
                  startDateTime: '2020-08-17T08:30:00+01:00'
                  endDateTime: '2020-12-18T00:30:00+01:00'
                  personCount: 183
                  otherCodes:
                    - codeType: identifier
                      code: 1234qwe12
                  organisationId: 452c1a86-a0af-475b-b03f-724878b0f387
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /groups/{groupId}/memberships:
    get:
      summary: GET /groups/{groupId}/memberships
      operationId: listMembershipsByGroupId
      description: Get an ordered list of membershipItems (personIds that are member of a given group, and duration) ordered by personId.
      tags:
        - groups
      parameters:
        - name: groupId
          in: path
          description: Group ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Membership'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /groups/{groupId}/memberships/{personId}:
    put:
      summary: PUT /groups/{groupId}/memberships/{personId}
      operationId: replacePersoninGroupById
      description: Replace or add a single group member from source system to recipient.
      tags:
        - groups
      parameters:
        - name: groupId
          in: path
          description: Group ID
          required: true
          schema:
            type: string
            format: uuid
        - name: personId
          in: path
          description: membership ID based on person ID since a person can only be once in a group
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Membership'
              title: membership
            examples:
              Create a new group member in remote system:
                value:
                  personId: 123e4567-e89b-12d3-a456-122564174000
                  groupId: 123e4567-e89b-12d3-a456-122564174000
                  startDateTime: '2025-09-28T08:30:00+01:00'
                  endDateTime: '2025-11-30T20:00:00+01:00'
                  state: active
                  role: student
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /learning-component-offering-associations/{learningComponentOfferingAssociationId}:
    get:
      summary: GET /learning-component-offering-associations/{learningComponentOfferingAssociationId}
      operationId: listLearningComponentOfferingAssociationById
      description: Get a single learning component offering association.
      tags:
        - learning component offering associations
      parameters:
        - name: learningComponentOfferingAssociationId
          in: path
          description: Course Offering Association ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - person
                - learning_component_offering
                - rooms
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LearningComponentOfferingAssociation'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /learning-component-offering-associations/{learningComponentOfferingAssociationId}
      description: |
        PUT a single learning component offering association to enrol a person on a specific association that can later be retrieved. 
      operationId: replaceLearningComponentOfferingAssociationById
      tags:
        - learning component offering associations
      parameters:
        - name: learningComponentOfferingAssociationId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LearningComponentOfferingAssociation'
            examples:
              Add student to created offering (zitting) (flow 2.2.B and 2.3):
                value:
                  associationId: 123e4567-e89b-12d3-a456-426614174000
                  role: student
                  state: associated
                  consumer:
                    consumerKey: nl-test-admin
                    extraTimeInMin: 30
                    personalNeeds:
                      - extraTime
                      - spoken
                      - spell-checker-on-screen
                  person:
                    personId: 123e4567-e89b-12d3-a456-426614174000
                    primaryCode:
                      codeType: student_number
                      code: '1234567'
                    givenName: Maartje
                    preferredName: Maar
                    surnamePrefix: van
                    surname: Damme
                    displayName: Maartje van Damme
                    activeEnrolment: true
                    affiliations:
                      - student
                    email: vandamme.mcw@student.roc.nl
                    languageOfChoice:
                      - nl-NL
                    otherCodes:
                      - codeType: accountId
                        code: s1234567@student.roc.nl
                      - codeType: eckid
                        code: https://roc.nl/8078d3...28bc85
                  learningComponentOfferingId: 123e4567-e89b-12d3-a456-134564174000
              Change student enrolment to offering (zitting) (flow 2.x):
                value:
                  associationId: 123e4567-e89b-12d3-a456-426614174000
                  role: student
                  state: associated
                  consumer:
                    consumerKey: nl-test-admin
                    extraTimeInMin: 30
                    personalNeeds:
                      - extraTime
                      - spoken
                      - spell-checker-on-screen
                  personId: 123e4567-e89b-12d3-a456-426614174000
                  learningComponentOfferingId: 123e4567-e89b-12d3-a456-134564174000
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    patch:
      summary: PATCH /learning-component-offering-associations/{learningComponentOfferingAssociationId}
      operationId: partialUpdateLearningComponentOfferingAssociationById
      description: |
        Update the status or result of an enrolment. Other elements of the association object COULD 
        also be PATCHED. But are not likely and have therefore not been included in this endpoint.
        Implementation of the PATCH activity is based on use PATCH with JSON Merge Patch standard, 
        a specialized media type `application/merge-patch+json` for partial resource representation 
        to update parts of resource objects.

        Security must be implemented at the level of the actual deployment rather than in the core 
        specification. This means that the specification remains neutral, while concrete security 
        measures can be applied in practice using established techniques such as OpenID with fine-grained 
        scopes (for example, write access on associations). The previous inline declaration has therefore
        been removed to avoid conflating implementation details with the specification.
      tags:
        - learning component offering associations
      parameters:
        - name: learningComponentOfferingAssociationId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/merge-patch+json:
            schema:
              properties:
                remoteState:
                  $ref: '#/components/schemas/remoteAssociationState'
                result:
                  $ref: '#/components/schemas/LearningComponentOfferingAssociationResult'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/AssociationId'
                  - $ref: '#/components/schemas/PostResponse'
                  - properties:
                      state:
                        $ref: '#/components/schemas/associationState'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /learning-component-offerings/{learningComponentOfferingId}:
    get:
      summary: GET /learning-component-offerings/{learningComponentOfferingId}
      operationId: listLearningComponentOfferingsById
      description: Get a single learnig component offering.
      tags:
        - learning component offerings
      parameters:
        - name: learningComponentOfferingId
          in: path
          description: Learning Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - learning_component
                - organisation
                - rooms
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LearningComponentOffering'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /learning-component-offerings/{learningComponentOfferingId}
      operationId: replaceLearningComponentOfferingsById
      description: Update all attributes of a single learning component offering.
      tags:
        - learning component offerings
      parameters:
        - name: learningComponentOfferingId
          in: path
          description: Learning Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LearningComponentOffering'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    patch:
      summary: PATCH /learning-component-offerings/{learningComponentOfferingId}
      operationId: partialUpdateLearningComponentOfferingsById
      description: Change attributes of a single learning component offering.
      tags:
        - learning component offerings
      parameters:
        - name: learningComponentOfferingId
          in: path
          description: Learning Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/LearningComponentOffering'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /learning-component-offerings/{learningComponentOfferingId}/groups:
    get:
      summary: GET /learning-component-offerings/{learningComponentOfferingId}/groups
      operationId: listGroupsByLearningComponentOfferingId
      description: Get an ordered list of all groups related to a learning component offering, ordered by name.
      tags:
        - groups
      parameters:
        - name: learningComponentOfferingId
          in: path
          description: Learning Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - name: groupType
          in: query
          description: Filter by group type
          required: false
          schema:
            $ref: '#/components/schemas/groupType'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Group'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /learning-component-offerings/{learningComponentOfferingId}/learning-component-offering-associations:
    get:
      summary: GET /learning-component-offerings/{learningComponentOfferingId}/learning-component-offering-associations
      operationId: listLearningComponentOfferingAssociationsByLearningComponentOfferingId
      description: Get a list of all learning component offering associations related to the learning component offering based on its ID.
      tags:
        - learning component offering associations
      parameters:
        - name: learningComponentOfferingId
          in: path
          description: Learning Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - name: role
          in: query
          description: Filter by role
          required: false
          schema:
            $ref: '#/components/schemas/associationRole'
        - name: state
          in: query
          description: Filter by state
          required: false
          schema:
            $ref: '#/components/schemas/associationState'
        - name: resultState
          in: query
          description: Filter by result state
          required: false
          schema:
            $ref: '#/components/schemas/resultState'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningComponentOfferingAssociation'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /learning-components:
    get:
      summary: GET /learning-components
      operationId: listLearningComponents
      description: Get a list of all learning components, ordered by name (ascending).
      tags:
        - learning components
      parameters:
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningComponent'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /learning-components/{learningComponentId}:
    get:
      summary: GET /learning-components/{learningComponentId}
      operationId: listLearningComponentById
      description: Get a single learnig component.
      tags:
        - learning components
      parameters:
        - name: learningComponentId
          in: path
          description: learning component ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - course
                - organisation
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LearningComponent'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /learning-components/{learningComponentId}/learning-component-offerings:
    get:
      summary: GET /learning-components/{learningComponentId}/learning-component-offerings
      operationId: listOfferingsByLearningComponentId
      description: Get a list of all learning component offerings for this learning component, ordered chronologically.
      tags:
        - learning component offerings
      parameters:
        - name: learningComponentId
          in: path
          description: Learning Component ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /learning-outcomes:
    get:
      summary: GET /learning-outcomes
      operationId: listLearningOutcomes
      description: Get a list of all learning outcomes, ordered chronologically.
      tags:
        - learning outcomes
      parameters:
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningOutcome'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /learning-outcomes/{learningOutcomeId}:
    get:
      summary: GET /learning-outcomes/{learningOutcomeId}
      operationId: listLearningOutcomeById
      description: Get a single learnig outcome.
      tags:
        - learning outcomes
      parameters:
        - name: learningOutcomeId
          in: path
          description: learning outcome component ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - organisation
                - parents
                - children
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/LearningOutcome'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations:
    get:
      summary: GET /organisations
      operationId: listOrganisations
      description: Get an ordered list of all organisations, ordered by name.
      tags:
        - organisations
      parameters:
        - $ref: '#/components/parameters/primaryCode'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - name: organisationType
          in: query
          description: Filter by organisation type
          required: false
          schema:
            $ref: '#/components/schemas/organisationType'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Organisation'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}:
    get:
      summary: GET /organisations/{organisationId}
      operationId: listOrganisationById
      description: Get a single organisation.
      tags:
        - organisations
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - parent
                - children
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Organisation'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /organisations/{organisationId}
      operationId: replaceOrganisationById
      description: change the data of a single organisation.
      tags:
        - organisations
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Organisation'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}/course-offerings:
    get:
      summary: GET /organisations/{organisationId}/course-offerings
      operationId: listCourseOfferingsByOrganisationId
      description: Get a list of all course offerings for a given organisation
      tags:
        - course offerings
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/CourseOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}/courses:
    get:
      summary: GET /organisations/{organisationId}/courses
      operationId: listCoursesByOrganisationId
      description: Get an ordered list of all courses for a given organisation, ordered by name.
      tags:
        - courses
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - name: level
          in: query
          description: Filter by level
          required: false
          schema:
            $ref: '#/components/schemas/level'
        - name: modeOfDelivery
          in: query
          description: Filter by modeOfDelivery
          required: false
          schema:
            $ref: '#/components/schemas/modeOfDelivery'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Course'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}/groups:
    get:
      summary: GET /organisations/{organisationId}/groups
      operationId: listGroupsByOrganisationId
      description: Get an ordered list of all groups for a given organisation, ordered by name.
      tags:
        - groups
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - name: groupType
          in: query
          description: Filter by group type
          required: false
          schema:
            $ref: '#/components/schemas/groupType'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Group'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}/learning-component-offerings:
    get:
      summary: GET /organisations/{organisationId}/learning-component-offerings
      operationId: listLearningComponentOfferingsByOrganisationId
      description: Get a list of all learning component offerings for a given organisation
      tags:
        - learning component offerings
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment (dateTime) for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment (dateTime) for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}/learning-components:
    get:
      summary: GET /organisations/{organisationId}/learning-components
      operationId: listLearningComponentsByOrganisationId
      description: Get an ordered list of all learning components for a given organisation, ordered by name.
      tags:
        - learning components
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/LearningComponent'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}/programme-offerings:
    get:
      summary: GET /organisations/{organisationId}/programme-offerings
      operationId: listProgrammeOfferingsByOrganisationId
      description: Get a list of all programme offerings for a given organisation
      tags:
        - programme offerings
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment (dateTime) for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment (dateTime) for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/ProgrammeOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}/programmes:
    get:
      summary: GET /organisations/{organisationId}/programmes
      operationId: listProgrammesByOrganisationId
      description: Get an ordered list of all programmes for a given organisation, ordered by name.
      tags:
        - programmes
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - name: programmeType
          in: query
          description: Filter by programme type
          required: false
          schema:
            $ref: '#/components/schemas/programmeType'
        - name: qualificationAwarded
          in: query
          description: Filter by qualificationAwarded
          required: false
          schema:
            $ref: '#/components/schemas/qualificationAwarded'
        - name: levelOfQualification
          in: query
          description: Filter by levelOfQualification
          required: false
          schema:
            $ref: '#/components/schemas/levelOfQualification'
        - name: fieldsOfStudy
          in: query
          description: Filter by fieldsOfStudy
          required: false
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Programme'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}/test-component-offerings:
    get:
      summary: GET /organisations/{organisationId}/test-component-offerings
      operationId: listTestComponentOfferingsByOrganisationId
      description: Get a list of all test component offerings for a given organisation
      tags:
        - test component offerings
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment (dateTime) for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment (dateTime) for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /organisations/{organisationId}/test-components:
    get:
      summary: GET /organisations/{organisationId}/test-components
      operationId: listTestComponentsByOrganisationId
      description: Get an ordered list of all test components for a given organisation, ordered by name.
      tags:
        - test components
      parameters:
        - name: organisationId
          in: path
          description: Organisation ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponent'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /persons:
    get:
      summary: GET /persons
      operationId: listPersons
      description: Get an ordered list of all persons.
      tags:
        - persons
      parameters:
        - $ref: '#/components/parameters/primaryCode'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/personSearch'
        - name: affiliations
          in: query
          description: Filter by affiliations
          required: false
          schema:
            $ref: '#/components/schemas/personAffiliation'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Person'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    post:
      summary: POST /persons
      operationId: createPerson
      description: POST a single person.
      tags:
        - persons
      requestBody:
        required: true
        content:
          application/json:
            schema:
              allOf:
                - $ref: '#/components/schemas/PersonProperties'
      responses:
        '201':
          description: Created
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/PersonId'
                  - $ref: '#/components/schemas/PostResponse'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /persons/me:
    get:
      summary: GET /persons/me
      operationId: listPersonByMyOauthId
      description: |
        Returns the person object for the currently authenticated user.

        Security must be implemented at the level of the actual deployment rather than in the core 
        specification. This means that the specification remains neutral, while concrete security 
        measures can be applied in practice using established techniques such as OpenID with 
        fine-grained scopes.
      tags:
        - persons
      parameters:
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Person'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /persons/{personId}:
    get:
      summary: GET /persons/{personId}
      operationId: listPersonById
      description: Get a single person.
      tags:
        - persons
      parameters:
        - name: personId
          in: path
          description: User ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Person'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /persons/{personId}
      operationId: replacePersonById
      description: change the data of a single person.
      tags:
        - persons
      parameters:
        - name: personId
          in: path
          description: User ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/Person'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /persons/{personId}/course-offering-associations:
    get:
      summary: GET /persons/{personId}/course-offering-associations
      operationId: listCourseOfferingAssociationsByPersonId
      description: Get a list of all course offering associations for an individual person.
      tags:
        - course offering associations
      parameters:
        - name: personId
          in: path
          description: Person ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - name: role
          in: query
          description: Filter by role
          required: false
          schema:
            $ref: '#/components/schemas/associationRole'
        - name: state
          in: query
          description: Filter by state
          required: false
          schema:
            $ref: '#/components/schemas/associationState'
        - name: resultState
          in: query
          description: Filter by result state
          required: false
          schema:
            $ref: '#/components/schemas/resultState'
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - academic_session
                - course_offering
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          allOf:
                            - $ref: '#/components/schemas/CourseOfferingAssociation'
                            - type: object
                              properties:
                                academicSession:
                                  $ref: '#/components/schemas/AcademicSession'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /persons/{personId}/learning-component-offering-associations:
    get:
      summary: GET /persons/{personId}/learning-component-offering-associations
      operationId: listLearningComponentOfferingAssociationsByPersonId
      description: Get a list of all learning component offering associations for an individual person.
      tags:
        - learning component offering associations
      parameters:
        - name: personId
          in: path
          description: Person ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
        - name: role
          in: query
          description: Filter by role
          required: false
          schema:
            $ref: '#/components/schemas/associationRole'
        - name: state
          in: query
          description: Filter by state
          required: false
          schema:
            $ref: '#/components/schemas/associationState'
        - name: resultState
          in: query
          description: Filter by result state
          required: false
          schema:
            $ref: '#/components/schemas/resultState'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          allOf:
                            - $ref: '#/components/schemas/LearningComponentOfferingAssociation'
                            - type: object
                              properties:
                                academicSession:
                                  $ref: '#/components/schemas/AcademicSession'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /persons/{personId}/programme-offering-associations:
    get:
      summary: GET /persons/{personId}/programme-offering-associations
      operationId: listProgrammeOfferingAssociationsByPersonId
      description: Get a list of all programme offering associations for an individual person.
      tags:
        - programme offering associations
      parameters:
        - name: personId
          in: path
          description: Person ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - name: role
          in: query
          description: Filter by role
          required: false
          schema:
            $ref: '#/components/schemas/associationRole'
        - name: state
          in: query
          description: Filter by state
          required: false
          schema:
            $ref: '#/components/schemas/associationState'
        - name: resultState
          in: query
          description: Filter by result state
          required: false
          schema:
            $ref: '#/components/schemas/resultState'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          allOf:
                            - $ref: '#/components/schemas/ProgrammeOfferingAssociation'
                            - type: object
                              properties:
                                academicSession:
                                  $ref: '#/components/schemas/AcademicSession'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /persons/{personId}/test-component-offering-associations:
    get:
      summary: GET /persons/{personId}/test-component-offering-associations
      operationId: listTestComponentOfferingAssociationsByPersonId
      description: Get a list of all test component offering associations for an individual person.
      tags:
        - test component offering associations
      parameters:
        - name: personId
          in: path
          description: Person ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - name: role
          in: query
          description: Filter by role
          required: false
          schema:
            $ref: '#/components/schemas/associationRole'
        - name: state
          in: query
          description: Filter by state
          required: false
          schema:
            $ref: '#/components/schemas/associationState'
        - name: resultState
          in: query
          description: Filter by result state
          required: false
          schema:
            $ref: '#/components/schemas/resultState'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          allOf:
                            - $ref: '#/components/schemas/TestComponentOfferingAssociation'
                            - type: object
                              properties:
                                academicSession:
                                  $ref: '#/components/schemas/AcademicSession'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programme-offering-associations/external/me:
    post:
      summary: POST /programme-offering-associations/external/me
      operationId: createExternalProgrammeOfferingAssociationByopenId
      description: |
        POST a single programme offering association, enrol a person based on person information obtained from well known endpoint, an offering, 
        and the organisation/type=root information from the organisation that is issuing this association. 
        The offering can either be identified by an offeringId if known or the full offering details. 

        Security must be implemented at the level of the actual deployment rather than in the core specification. 
        This means that the specification remains neutral, while concrete security measures can be applied in 
        practice using established techniques such as OpenID with fine-grained scopes. For example, write access 
        on programme-offering associations for an external user (“me.write”) can be granted in this way. The previous 
        inline declaration has therefore been removed to avoid conflating implementation details with the specification.
      tags:
        - programme offering associations
      requestBody:
        required: true
        content:
          application/json:
            schema:
              required:
                - remoteState
              allOf:
                - $ref: '#/components/schemas/ProgrammeOfferingAssociationExternalMe'
                - properties:
                    issuer:
                      $ref: '#/components/schemas/Organisation'
      responses:
        '201':
          description: CREATED
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/AssociationId'
                  - $ref: '#/components/schemas/PostResponse'
                  - properties:
                      state:
                        $ref: '#/components/schemas/associationState'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programme-offering-associations/{programmeOfferingAssociationId}:
    get:
      summary: GET /programme-offering-associations/{programmeOfferingAssociationId}
      operationId: listProgrammeOfferingAssociationById
      description: Get a single programme offering association.
      tags:
        - programme offering associations
      parameters:
        - name: programmeOfferingAssociationId
          in: path
          description: Programme offering association ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - person
                - programme_offering
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProgrammeOfferingAssociation'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /programme-offering-associations/{programmeOfferingAssociationId}
      description: |
        PUT a single programme offering association to enrol a person on a specific association that can later be retrieved.  
      operationId: replaceProgrammeOfferingAssociationById
      tags:
        - programme offering associations
      parameters:
        - name: programmeOfferingAssociationId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProgrammeOfferingAssociation'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    patch:
      summary: PATCH /programme-offering-associations/{programmeOfferingAssociationId}
      operationId: partialUpdateProgrammeOfferingAssociationById
      description: |
        Update the status or result of an enrolment. Other elements of the association object COULD 
        also be PATCHED. But are not likely and have therefore not been included in this endpoint.
        Implementation of the PATCH activity is based on use PATCH with JSON Merge Patch standard, 
        a specialized media type `application/merge-patch+json` for partial resource representation 
        to update parts of resource objects.

        Security must be implemented at the level of the actual deployment rather than in the core 
        specification. This means that the specification remains neutral, while concrete security 
        measures can be applied in practice using established techniques such as OpenID with fine-grained 
        scopes (for example, write access on associations). The previous inline declaration has therefore
        been removed to avoid conflating implementation details with the specification.
      tags:
        - programme offering associations
      parameters:
        - name: programmeOfferingAssociationId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/merge-patch+json:
            schema:
              properties:
                remoteState:
                  $ref: '#/components/schemas/remoteAssociationState'
                result:
                  $ref: '#/components/schemas/ProgrammeOfferingAssociationResult'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/AssociationId'
                  - $ref: '#/components/schemas/PostResponse'
                  - properties:
                      state:
                        $ref: '#/components/schemas/associationState'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programme-offerings/{programmeOfferingId}:
    get:
      summary: GET /programme-offerings/{programmeOfferingId}
      operationId: listProgrammeOfferingsById
      description: Get a single programme offering.
      tags:
        - programme offerings
      parameters:
        - name: programmeOfferingId
          in: path
          description: Programme Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - academic_session
                - course
                - course_offering
                - learning_component
                - organisation
                - programme
                - programme_offering
                - test_component
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProgrammeOffering'
                title: programmeOffering
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /programme-offerings/{programmeOfferingId}
      operationId: replaceProgrammeOfferingsById
      description: Update all attributes of a single programme offering.
      tags:
        - programme offerings
      parameters:
        - name: programmeOfferingId
          in: path
          description: Programme Offering ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProgrammeOffering'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    patch:
      summary: PATCH /programme-offerings/{programmeOfferingId}
      operationId: partialUpdateProgrammeOfferingsById
      description: Change attributes of a single programme offering.
      tags:
        - programme offerings
      parameters:
        - name: programmeOfferingId
          in: path
          description: Programme Offering ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/ProgrammeOffering'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programme-offerings/{programmeOfferingId}/groups:
    get:
      summary: GET /programme-offerings/{programmeOfferingId}/groups
      operationId: listGroupsByProgrammeOfferingId
      description: Get an ordered list of all groups related to a programme offering, ordered by name.
      tags:
        - groups
      parameters:
        - name: programmeOfferingId
          in: path
          description: Programme Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - name: groupType
          in: query
          description: Filter by group type
          required: false
          schema:
            $ref: '#/components/schemas/groupType'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Group'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programme-offerings/{programmeOfferingId}/programme-offering-associations:
    get:
      summary: GET /programme-offerings/{programmeOfferingId}/programme-offering-associations
      operationId: listProgrammeOfferingAssociationsByProgrammeOfferingId
      description: Get a list of all programme offering associations related to the programme offering based on its ID.
      tags:
        - programme offering associations
      parameters:
        - name: programmeOfferingId
          in: path
          description: Programme Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - name: role
          in: query
          description: Filter by role
          required: false
          schema:
            $ref: '#/components/schemas/associationRole'
        - name: state
          in: query
          description: Filter by state
          required: false
          schema:
            $ref: '#/components/schemas/associationState'
        - name: resultState
          in: query
          description: Filter by result state
          required: false
          schema:
            $ref: '#/components/schemas/resultState'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/ProgrammeOfferingAssociation'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programmes:
    get:
      summary: GET /programmes
      operationId: listProgrammes
      description: Get an ordered list of all programmes, ordered by name.
      tags:
        - programmes
      parameters:
        - $ref: '#/components/parameters/primaryCode'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - name: programmeType
          in: query
          description: Filter by programme type
          required: false
          schema:
            $ref: '#/components/schemas/programmeType'
        - name: qualificationAwarded
          in: query
          description: Filter by qualificationAwarded
          required: false
          schema:
            $ref: '#/components/schemas/qualificationAwarded'
        - name: levelOfQualification
          in: query
          description: Filter by levelOfQualification
          required: false
          schema:
            $ref: '#/components/schemas/levelOfQualification'
        - name: fieldsOfStudy
          in: query
          description: Filter by fieldsOfStudy
          required: false
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Programme'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programmes/{programmeId}:
    get:
      summary: GET /programmes/{programmeId}
      operationId: listProgrammeById
      description: Get a single programme.
      tags:
        - programmes
      parameters:
        - name: programmeId
          in: path
          description: Programme ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to include, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - parent
                - children
                - coordinators
                - instructors
                - organisation
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/returnTimelineOverrides'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/ProgrammeExpanded'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programmes/{programmeId}/courses:
    get:
      summary: GET /programmes/{programmeId}/courses
      operationId: listCoursesByProgrammeId
      description: Get an ordered list of all courses given through this programme.
      tags:
        - courses
      parameters:
        - name: programmeId
          in: path
          description: Programme ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - name: level
          in: query
          description: Filter by level
          required: false
          schema:
            $ref: '#/components/schemas/level'
        - name: modeOfDelivery
          in: query
          description: Filter by modeOfDelivery
          required: false
          schema:
            $ref: '#/components/schemas/modeOfDelivery'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Course'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programmes/{programmeId}/programme-offerings:
    get:
      summary: GET /programmes/{programmeId}/programme-offerings
      operationId: listOfferingsByProgrammeId
      description: Get a list of all offerings for this programme, ordered chronologically.
      tags:
        - programme offerings
      parameters:
        - name: programmeId
          in: path
          description: Programme ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: modeOfStudy
          in: query
          description: Filter by modeOfStudy
          required: false
          schema:
            $ref: '#/components/schemas/modeOfStudy'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment (dateTime) for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment (dateTime) for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/ProgrammeOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /programmes/{programmeId}/programmes:
    get:
      summary: GET /programmes/{programmeId}/programmes
      operationId: listProgrammesByProgrammeId
      description: Get an ordered list of nested programmes, ordered by name.
      tags:
        - programmes
      parameters:
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - name: programmeId
          in: path
          description: the id of the programme to find nested programmes for
          required: true
          schema:
            type: string
            format: uuid
        - name: programmeType
          in: query
          description: Filter by programme type
          required: false
          schema:
            $ref: '#/components/schemas/programmeType'
        - name: qualificationAwarded
          in: query
          description: Filter by qualificationAwarded
          required: false
          schema:
            $ref: '#/components/schemas/qualificationAwarded'
        - name: levelOfQualification
          in: query
          description: Filter by levelOfQualification
          required: false
          schema:
            $ref: '#/components/schemas/levelOfQualification'
        - name: fieldsOfStudy
          in: query
          description: Filter by fieldsOfStudy
          required: false
          schema:
            type: string
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Programme'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /rooms:
    get:
      summary: GET /rooms
      operationId: listRooms
      description: Get a list of all rooms, ordered by name (ascending).
      tags:
        - rooms
      parameters:
        - $ref: '#/components/parameters/primaryCode'
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - name: roomType
          in: query
          description: Filter by room type
          required: false
          schema:
            $ref: '#/components/schemas/roomType'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Room'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /rooms/{roomId}:
    get:
      summary: GET /rooms/{roomId}
      operationId: listRoomById
      description: Get a single room.
      tags:
        - rooms
      parameters:
        - name: roomId
          in: path
          description: Room ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - building
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Room'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-component-offering-associations/{testComponentOfferingAssociationId}:
    get:
      summary: GET /test-component-offering-associations/{testComponentOfferingAssociationId}
      operationId: listTestComponentOfferingAssociationById
      description: Get a single test component offering association.
      tags:
        - test component offering associations
      parameters:
        - name: testComponentOfferingAssociationId
          in: path
          description: Test Component Offering Association ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - person
                - test_component_offering
                - rooms
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestComponentOfferingAssociation'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /test-component-offering-associations/{testComponentOfferingAssociationId}
      description: |
        PUT a single test component offering association to enrol a person on a specific association that can later be retrieved.  
      operationId: replaceTestComponentOfferingAssociationById
      tags:
        - test component offering associations
      parameters:
        - name: testComponentOfferingAssociationId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TestComponentOfferingAssociation'
            examples:
              Add student to created offering (zitting) (flow 2.2.B and 2.3):
                value:
                  associationId: 123e4567-e89b-12d3-a456-426614174000
                  role: student
                  state: associated
                  consumer:
                    consumerKey: nl-test-admin
                    extraTimeInMin: 30
                    personalNeeds:
                      - extraTime
                      - spoken
                      - spell-checker-on-screen
                  person:
                    personId: 123e4567-e89b-12d3-a456-426614174000
                    primaryCode:
                      codeType: studentNumber
                      code: '1234567'
                    givenName: Maartje
                    preferredName: Maar
                    surnamePrefix: van
                    surname: Damme
                    displayName: Maartje van Damme
                    activeEnrolment: true
                    affiliations:
                      - student
                    email: vandamme.mcw@student.roc.nl
                    languageOfChoice:
                      - nl-NL
                    otherCodes:
                      - codeType: accountId
                        code: s1234567@student.roc.nl
                      - codeType: eckid
                        code: https://roc.nl/8078d3...28bc85
                  testComponentOfferingId: 123e4567-e89b-12d3-a456-134564174000
              Change student enrolment to offering (zitting) (flow 2.x):
                value:
                  associationId: 123e4567-e89b-12d3-a456-426614174000
                  role: student
                  state: associated
                  consumer:
                    consumerKey: nl-test-admin
                    extraTimeInMin: 30
                    personalNeeds:
                      - extraTime
                      - spoken
                      - spell-checker-on-screen
                  personId: 123e4567-e89b-12d3-a456-426614174000
                  testComponentOfferingId: 123e4567-e89b-12d3-a456-134564174000
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    patch:
      summary: PATCH /test-component-offering-associations/{testComponentOfferingAssociationId}
      operationId: partialUpdateTestComponentOfferingAssociationById
      description: |
        Update the status or result of an enrolment. Other elements of the association object COULD 
        also be PATCHED. But are not likely and have therefore not been included in this endpoint.
        Implementation of the PATCH activity is based on use PATCH with JSON Merge Patch standard, 
        a specialized media type `application/merge-patch+json` for partial resource representation 
        to update parts of resource objects.

        Security must be implemented at the level of the actual deployment rather than in the core 
        specification. This means that the specification remains neutral, while concrete security 
        measures can be applied in practice using established techniques such as OpenID with fine-grained 
        scopes (for example, write access on associations). The previous inline declaration has therefore
        been removed to avoid conflating implementation details with the specification.
      tags:
        - test component offering associations
      parameters:
        - name: testComponentOfferingAssociationId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/merge-patch+json:
            schema:
              properties:
                remoteState:
                  $ref: '#/components/schemas/remoteAssociationState'
                result:
                  $ref: '#/components/schemas/TestComponentOfferingAssociationResult'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/AssociationId'
                  - $ref: '#/components/schemas/PostResponse'
                  - properties:
                      state:
                        $ref: '#/components/schemas/associationState'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-component-offering-associations/{testComponentOfferingAssociationId}/url:
    get:
      summary: GET /test-component-offering-associations/{testComponentOfferingAssociationId}/url
      description: |
        Get the URL of the test component association to start the testing tool.
      operationId: listTestComponentOfferingAssociationUrl
      tags:
        - test component offering associations
      parameters:
        - name: testComponentOfferingAssociationId
          in: path
          description: Association ID
          required: true
          schema:
            type: string
            format: uuid
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/Url'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-component-offering-associations/{testComponentOfferingAssociationId}/test-component-offering-association-attempts:
    get:
      summary: GET /test-component-offering-associations/{testComponentOfferingAssociationId}/test-component-offering-association-attempts
      operationId: listTestComponentOfferingAssociationAttemptsByTestComponentOfferingAssociationId
      description: Get a list of all test component offering association attempts related to the test component offering association based on its ID.
      tags:
        - test component offering association attempts
      parameters:
        - name: testComponentOfferingAssociationId
          in: path
          description: Test Component Offering Association ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - name: attendance
          in: query
          description: Filter by attendance
          required: false
          schema:
            $ref: '#/components/schemas/attendance'
        - name: state
          in: query
          description: Filter by state
          required: false
          schema:
            $ref: '#/components/schemas/attemptState'
        - name: resultState
          in: query
          description: Filter by result state
          required: false
          schema:
            $ref: '#/components/schemas/resultState'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponentOfferingAssociationAttempt'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-component-offering-associations/{testComponentOfferingAssociationId}/test-component-offering-association-attempt/{testComponentOfferingAssociationAttemptId}:
    put:
      summary: PUT /test-component-offering-associations/{testComponentOfferingAssociationId}/test-component-offering-association-attempt/{testComponentOfferingAssociationAttemptId}
      description: |
        PUT a single test component offering association attempt to enrol a person on a specific attempt or update information on that enrolment that can later be retrieved.
        An additional path is supported for systems that need to process attempt results based on the association ID the attempt belongs to.
      operationId: insertOrReplaceTestComponentOfferingAssociationAttemptByAssociationIdAndAttemptId
      tags:
        - test component offering association attempts
      parameters:
        - name: testComponentOfferingAssociationId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
        - name: testComponentOfferingAssociationAttemptId
          in: path
          description: The id of the attempt to update
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/fields'
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TestComponentOfferingAssociationAttempt'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-component-offering-associations-attempt/{testComponentOfferingAssociationAttemptId}:
    get:
      summary: GET /test-component-offering-association-attempts/{testComponentOfferingAssociationAttemptId}
      operationId: listTestComponentOfferingAssociationAttemptById
      description: Get a single test component offering association attempt.
      tags:
        - test component offering association attempts
      parameters:
        - name: testComponentOfferingAssociationAttemptId
          in: path
          description: Test Component Offering Association Attempt ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestComponentOfferingAssociationAttemptFull'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /test-component-offering-association-attempts/{testComponentOfferingAssociationAttemptId}
      description: |
        PUT a single test component offering association attempt to enrol a person in a specific attempt or 
        update information on that enrolment that can later be retrieved.
      operationId: insertOrReplaceTestComponentOfferingAssociationAttemptById
      tags:
        - test component offering association attempts
      parameters:
        - name: testComponentOfferingAssociationAttemptId
          in: path
          description: The id of the association to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TestComponentOfferingAssociationAttemptFull'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    patch:
      summary: PATCH /test-component-offering-association-attempts/{testComponentOfferingAssociationAttemptId}
      operationId: partialUpdateTestComponentOfferingAssociationAttemptById
      description: |
        Update the result of an attempt. Other elements of the attempt object COULD 
        also be PATCHED. But are not likely and have therefore not been included in this endpoint.
        Implementation of the PATCH activity is based on use PATCH with JSON Merge Patch standard, 
        a specialized media type `application/merge-patch+json` for partial resource representation 
        to update parts of resource objects.
      tags:
        - test component offering association attempts
      parameters:
        - name: testComponentOfferingAssociationAttemptId
          in: path
          description: The id of the association attempt to update
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/merge-patch+json:
            schema:
              properties:
                result:
                  $ref: '#/components/schemas/Result'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/AssociationId'
                  - $ref: '#/components/schemas/PostResponse'
                  - properties:
                      state:
                        $ref: '#/components/schemas/associationState'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-component-offerings/{testComponentOfferingId}:
    get:
      summary: GET /test-component-offerings/{testComponentOfferingId}
      operationId: listTestComponentOfferingsById
      description: Get a single learnig component offering.
      tags:
        - test component offerings
      parameters:
        - name: testComponentOfferingId
          in: path
          description: Test Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - test_component
                - organisation
                - rooms
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestComponentOffering'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    put:
      summary: PUT /test-component-offerings/{testComponentOfferingId}
      operationId: replaceTestComponentOfferingsById
      description: Update all attributes of a single test component offering.
      tags:
        - test component offerings
      parameters:
        - name: testComponentOfferingId
          in: path
          description: Test Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TestComponentOffering'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
    patch:
      summary: PATCH /test-component-offerings/{testComponentOfferingId}
      operationId: partialUpdateTestComponentOfferingsById
      description: Change attributes of a single test component offering.
      tags:
        - test component offerings
      parameters:
        - name: testComponentOfferingId
          in: path
          description: Test Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
      requestBody:
        required: true
        content:
          application/json:
            schema:
              $ref: '#/components/schemas/TestComponentOffering'
      responses:
        '200':
          description: OK
        '201':
          description: Created
        '202':
          description: Accepted
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-component-offerings/{testComponentOfferingId}/groups:
    get:
      summary: GET /test-component-offerings/{testComponentOfferingId}/groups
      operationId: listGroupsByTestComponentOfferingId
      description: Get an ordered list of all groups related to a test component offering, ordered by name.
      tags:
        - groups
      parameters:
        - name: testComponentOfferingId
          in: path
          description: Test Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - name: groupType
          in: query
          description: Filter by group type
          required: false
          schema:
            $ref: '#/components/schemas/groupType'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/Group'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-component-offerings/{testComponentOfferingId}/test-component-offering-associations:
    get:
      summary: GET /test-component-offerings/{testComponentOfferingId}/test-component-offering-associations
      operationId: listTestComponentOfferingAssociationsByTestComponentOfferingId
      description: Get a list of all test component offering associations related to the test component offering based on its ID.
      tags:
        - test component offering associations
      parameters:
        - name: testComponentOfferingId
          in: path
          description: Test Component Offering ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - name: role
          in: query
          description: Filter by role
          required: false
          schema:
            $ref: '#/components/schemas/associationRole'
        - name: state
          in: query
          description: Filter by state
          required: false
          schema:
            $ref: '#/components/schemas/associationState'
        - name: resultState
          in: query
          description: Filter by result state
          required: false
          schema:
            $ref: '#/components/schemas/resultState'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponentOfferingAssociation'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-components:
    get:
      summary: GET /test-components
      operationId: listTestComponents
      description: Get a list of all test components, ordered by name.
      tags:
        - test components
      parameters:
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponent'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-components/{testComponentId}:
    get:
      summary: GET /test-components/{testComponentId}
      operationId: listTestComponentById
      description: Get a single test component.
      tags:
        - test components
      parameters:
        - name: testComponentId
          in: path
          description: component ID
          required: true
          schema:
            type: string
            format: uuid
        - name: expand
          in: query
          explode: false
          description: Optional properties to expand, separated by a comma
          required: false
          style: form
          schema:
            type: array
            items:
              type: string
              enum:
                - course
                - organisation
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/consumer'
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                $ref: '#/components/schemas/TestComponent'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
  /test-components/{testComponentId}/test-component-offerings:
    get:
      summary: GET /test-components/{testComponentId}/test-component-offerings
      operationId: listOfferingsByTestComponentId
      description: Get a list of all offerings for this test component, ordered chronologically.
      tags:
        - test component offerings
      parameters:
        - name: testComponentId
          in: path
          description: Test Component ID
          required: true
          schema:
            type: string
            format: uuid
        - $ref: '#/components/parameters/pageSize'
        - $ref: '#/components/parameters/pageNumber'
        - $ref: '#/components/parameters/consumer'
        - $ref: '#/components/parameters/filterQuery'
        - $ref: '#/components/parameters/filterQueryOr'
        - $ref: '#/components/parameters/fields'
        - $ref: '#/components/parameters/search'
        - $ref: '#/components/parameters/teachingLanguage'
        - $ref: '#/components/parameters/offeringState'
        - name: resultExpected
          in: query
          description: Filter by resultExpected
          required: false
          schema:
            type: boolean
        - name: since
          in: query
          description: Filter all offerings by providing a minimum start moment (dateTime) for the corresponding academic session, RFC3339 (full-date). By default only future offerings are shown (equal to `?since=<today>`).
          required: false
          schema:
            type: string
            format: date-time
        - name: until
          in: query
          description: Filter all offerings by providing a maximum end moment (dateTime) for the corresponding academic session, RFC3339 (full-date).
          required: false
          schema:
            type: string
            format: date-time
      responses:
        '200':
          description: OK
          content:
            application/json:
              schema:
                allOf:
                  - $ref: '#/components/schemas/Pagination'
                  - type: object
                    required:
                      - items
                    properties:
                      items:
                        type: array
                        items:
                          $ref: '#/components/schemas/TestComponentOffering'
                      ext:
                        $ref: '#/components/schemas/Ext'
        '400':
          $ref: '#/components/responses/ErrorBadRequest'
        '401':
          $ref: '#/components/responses/ErrorUnauthorized'
        '403':
          $ref: '#/components/responses/ErrorForbidden'
        '404':
          $ref: '#/components/responses/ErrorNotFound'
        '405':
          $ref: '#/components/responses/ErrorMethodNotAllowed'
        '406':
          $ref: '#/components/responses/ErrorNotAcceptable'
        '429':
          $ref: '#/components/responses/ErrorTooManyRequests'
        '500':
          $ref: '#/components/responses/ErrorInternalServerError'
components:
  schemas:
    Service:
      type: object
      description: A metadata set providing details on the provider of this OOAPI implementation
      required:
        - contactEmail
        - specification
      properties:
        contactEmail:
          type: string
          description: Contact e-mail address of the service owner
          format: email
          maxLength: 256
          example: admin@universiteitvanharderwijk.nl
        specification:
          type: string
          description: URL of the API specification (YAML or JSON, compliant with [Open API Specification v3](https://github.com/OAI/OpenAPI-Specification/))
          format: uri
          maxLength: 2048
          example: https://rawgit.com/open-education-api/specification/v3/docs.html#tag/course-offerings/paths/~1course-offerings/get
        documentation:
          type:
            - string
            - 'null'
          description: URL of the API documentation, including general terms and privacy statement
          format: uri
          maxLength: 2048
          example: https://open-education-api.github.io/specification/v4/docs.html
        supportedConsumers:
          type:
            - array
            - 'null'
          items:
            type: object
            description: Object for communicating data to a specific consumer (destination). This object has no relationship with the consumer query parameter.
            required:
              - consumerKey
              - version
            properties:
              consumerKey:
                description: The key of the consumer (destination) for which this information is intended. See the consumer registry for more information.
                type: string
                example: nl-test-admin
              version:
                description: the version number of this consumer
                type: string
                example: 0.9.3
        supportedOperations:
          type:
            - array
            - 'null'
          items:
            type: object
            description: Object for communicating VERBS and endpoints that are supported by this implementation.
            required:
              - verbs
              - path
            properties:
              verbs:
                type: array
                description: The type of method or verb.
                items:
                  type: string
                  enum:
                    - GET
                    - PUT
                    - PATCH
                    - POST
                  example: GET
              path:
                description: the path of the operation
                type: string
                format: uri-reference
                maxLength: 2048
                example: /courses
        supportedExpands:
          type:
            - array
            - 'null'
          items:
            type: object
            description: Object for communicating the expands and paths for which they are implemented.
            required:
              - expandableObjects
              - path
            properties:
              expandableObjects:
                description: the objects that are expandable for a specific path
                type: array
                items:
                  $ref: '#/components/schemas/expandableObjects'
              path:
                description: the path of the operation
                type: string
                format: uri-reference
                maxLength: 2048
                example: /courses
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    AcademicSession:
      type: object
      description: |
        A named period of time that can be used to communicate the various schedules and time periods an institution recognizes and uses to organise their education. AcademicSessions can be nested.
        Offerings MAY be linked to a specific AcademicSession to indicate that the specified Offering takes place during the AcademicSession, however this is not mandatory.
      required:
        - academicSessionId
        - academicSessionType
        - primaryCode
        - name
        - startDateTime
        - endDateTime
      properties:
        academicSessionId:
          type: string
          description: Unique id for this academic session
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        academicSessionType:
          $ref: '#/components/schemas/academicSessionType'
        primaryCode:
          description: The primary human readable identifier for this academic session. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: identifier
            code: 2012-Q1
        name:
          type: array
          description: The name of this academic session
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Autumn term 2020
        abbreviation:
          type:
            - string
            - 'null'
          description: The abbreviation or internal code used to identify this AcademicSession
          maxLength: 256
          example: SPRING-2026
        startDateTime:
          type: string
          description: The moment on which this academic session starts, RFC3339 (full-date)
          format: date-time
          example: '2025-09-28T08:30:00+01:00'
        endDateTime:
          type: string
          description: The moment on which this academic session ends, RFC3339 (full-date)
          format: date-time
          example: '2025-09-28T08:30:00+01:00'
        parentId:
          description: |
            The identifier of the parent academicSession for this session (e.g. Autumn
            term 20xx where the current session is week 40).
            When the client does not request expansion of `parent`, only this
            identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        parent:
          description: |
            The expanded parent academicSession object of this session (e.g. Autumn
            term 20xx where the current session is week 40).
            When the client requests expansion of `parent`, the full expanded
            academicSession object MUST be returned here instead of only the identifier.
            If no parent is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/AcademicSession'
        childIds:
          description: |
            The list of identifiers of child academicSessions of this session (e.g. all
            academic sessions in Autumn term 20xx).
            When the client does not request expansion of `children`, only these
            identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).

            Although `childIds` and `children` (for example `organisationIds` versus `organisations`) may 
            seem unusual, this naming is intentional and follows the singular–plural convention defined 
            by the specification.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        children:
          description: |
            The expanded child academicSession objects of this session (e.g. all
            academic sessions in Autumn term 20xx).
            When the client requests expansion of `children`, the full expanded
            academicSession objects MUST be returned here instead of only the identifiers.
            If no child sessions are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/AcademicSession'
        yearId:
          description: |
            The identifier of the top-level academicSession year for this session
            (e.g. 20xx where the current session is week 40 of a semester).
            When the client does not request expansion of `year`, only this identifier
            is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        year:
          description: |
            The expanded top-level academicSession year object for this session
            (e.g. 20xx where the current session is week 40 of a semester).
            When the client requests expansion of `year`, the full expanded
            academicSession object MUST be returned here instead of only the identifier.
            If no top-level year is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/AcademicSession'
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    Building:
      type: object
      description: An object describing a building and the properties of a building.
      required:
        - buildingId
        - name
        - primaryCode
      properties:
        buildingId:
          type: string
          description: Unique id of this building
          format: uuid
          example: 123e4567-e89b-12d3-a456-331214174000
        primaryCode:
          description: The primary human readable identifier for this building. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: buildingId
            code: '45'
        abbreviation:
          type:
            - string
            - 'null'
          description: The abbreviation of the name of this building
          maxLength: 256
          example: Bb
        name:
          type: array
          description: The name of this building
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Beatrix building
        description:
          type:
            - array
            - 'null'
          description: The description of this building.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: external rooms location for exams
        address:
          oneOf:
            - $ref: '#/components/schemas/Address'
            - type: 'null'
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
          example:
            - codeType: bagId
              code: '0344100000139910'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    LearningComponent:
      type: object
      description: A component is a part of a course
      required:
        - componentId
        - componentType
        - name
        - primaryCode
      properties:
        componentId:
          type: string
          description: Unique id of this component
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        primaryCode:
          description: The primary human readable identifier for this component. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: componentCode
            code: INFOMQNM-WRKCLG-1
        componentType:
          $ref: '#/components/schemas/learningComponentType'
        name:
          type: array
          description: The name of this component
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Written test for INFOMQNM
        abbreviation:
          type:
            - string
            - 'null'
          description: The abbreviation of this component
          maxLength: 256
          example: Test-INFOMQNM
        modesOfDelivery:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/modeOfDelivery'
        duration:
          type:
            - string
            - 'null'
          description: The duration of this component. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339.
          pattern: ^-?P(?:\d+Y)?(?:\d+M)?(?:\d+(?:D|W))?(?:T(?:\d+H)?(?:\d+M)?(?:\d+(?:\.\d+)?S)?)?$
          example: P1DT10H30M
        description:
          type:
            - array
            - 'null'
          description: The description of this component.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: |
                'Prove executable knowledge of research methods, including: Acquire knowledge of HCI research paradigms Able to design suitable research studies (e.g., choose between within and between subject designs) Define/apply/design metrics and scales Define/produce materials (e.g., stimuli and questionnaires) Define protocols for research studies Understands and take in account concepts of reliability and validity Analyse and improve methods and analysis of published scientific articles Able to deliver scientific reports
                Prove executable knowledge of ­­­statistics, including: Handle hypothesis testing with complex designs (e.g., including , dependent, independent, and co variates) Data preparation (e.g., coding and feature selection) Reason towards adequate techniques to ensure valid outcomes (e.g., be aware of type I, type II errors) Select an appropriate sampling method (e.g., stratified) Perform parametric tests (e.g., repeated measures (M)ANOVA) Perform non-parametric tests (e.g., Chi-square, Mann-Whitney, and Kruskal-Wallis)'
        teachingLanguages:
          type:
            - array
            - 'null'
          description: The languages in which this learning component is given, should be three-letter language codes as specified by ISO 639-2. A student should be reasonably proficient in each language to be able to follow the learning component.
          minItems: 1
          items:
            $ref: '#/components/schemas/Language'
        learningOutcomeIds:
          description: |
            The identifiers of the learning outcomes related to this learning component.
            When the client does not request expansion of `learningOutcomes`, only these
            identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        learningOutcomes:
          description: |
            The expanded learning outcome objects related to this learning component.
            When the client requests expansion of `learningOutcomes`, the full expanded
            learning outcome objects MUST be returned here instead of only the identifiers.
            If no learning outcomes are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            type:
              - object
              - 'null'
            allOf:
              - $ref: '#/components/schemas/LearningOutcome'
        enrolment:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          description: The extra information that is provided for enrolment
          example:
            - language: en-GB
              value: enrolment through SIS. [The limited implementation of Git Hub Markdown syntax](https://openonderwijsapi.nl/v6.0/#/technical/formatting-text) MAY be used for rich text representation.
        resources:
          type:
            - array
            - 'null'
          description: An overview of the literature and other resources that is used in this course (ECTS-recommended reading and other sources)
          items:
            type: string
          example:
            - book to be announced
            - on-line resource x
        assessment:
          type:
            - array
            - 'null'
          description: A description of the way exams for this course are taken (ECTS-assessment method and criteria).
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Exam on campus
        addresses:
          type:
            - array
            - 'null'
          description: Addresses for this component
          items:
            $ref: '#/components/schemas/Address'
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
        parentId:
          description: |
            The identifier of the parent learningComponent of which the current learningComponent is a child.
            When the client does not request expansion of `parent`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        parent:
          description: |
            The expanded parent learningComponent of which the current learningComponent is a child.
            When the client requests expansion of `parent`, the full expanded learningComponent object MUST be returned here instead of only the identifier.
            If no parent is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/LearningComponent'
        childIds:
          description: |
            The identifiers of the learningComponents which are a part of this learningComponent (e.g. combined tests).
            When the client does not request expansion of `children`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).

            Although `childIds` and `children` (for example `organisationIds` versus `organisations`) may 
            seem unusual, this naming is intentional and follows the singular–plural convention defined 
            by the specification.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        children:
          description: |
            The expanded learningComponent objects which are a part of this learningComponent (e.g. combined tests).
            When the client requests expansion of `children`, the full expanded learningComponent objects MUST be returned here instead of only the identifiers.
            If no children are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            type:
              - object
              - 'null'
            allOf:
              - $ref: '#/components/schemas/LearningComponent'
        courseId:
          description: |
            The identifier of the course of which this component is a part.
            When the client does not request expansion of `course`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        course:
          description: |
            The expanded course object of which this component is a part.
            When the client requests expansion of `course`, the full expanded course object MUST be returned here instead of only the identifier.
            If no course is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Course'
        organisationId:
          description: |
            The identifier of the organisation which provides this component.
            When the client does not request expansion of `organisation`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        organisation:
          description: |
            The expanded organisation object which provides this component.
            When the client requests expansion of `organisation`, the full expanded organisation object MUST be returned here instead of only the identifier.
            If no organisation is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Organisation'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    TestComponent:
      type: object
      description: A component is a part of a course
      required:
        - componentId
        - componentType
        - name
        - primaryCode
      properties:
        componentId:
          type: string
          description: Unique id of this component
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        primaryCode:
          description: The primary human readable identifier for this component. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: componentCode
            code: INFOMQNM-WRKCLG-1
        componentType:
          $ref: '#/components/schemas/testComponentType'
        name:
          type: array
          description: The name of this component
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Written test for INFOMQNM
        abbreviation:
          type:
            - string
            - 'null'
          description: The abbreviation of this component
          maxLength: 256
          example: Test-INFOMQNM
        modesOfDelivery:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/modeOfDelivery'
        duration:
          type:
            - string
            - 'null'
          description: The duration of this component. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339.
          pattern: ^-?P(?:\d+Y)?(?:\d+M)?(?:\d+(?:D|W))?(?:T(?:\d+H)?(?:\d+M)?(?:\d+(?:\.\d+)?S)?)?$
          example: PT1H30M
        extraDuration:
          type:
            - string
            - 'null'
          description: The extra duration of this component for candidates that are awarded extra time as a personal need. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339.
          pattern: ^-?P(?:\d+Y)?(?:\d+M)?(?:\d+(?:D|W))?(?:T(?:\d+H)?(?:\d+M)?(?:\d+(?:\.\d+)?S)?)?$
          example: PT30M
        resultValueType:
          oneOf:
            - $ref: '#/components/schemas/resultValueType'
            - type: 'null'
        attempts:
          type:
            - integer
            - 'null'
          description: The number of attempts that are allowed for this component within one offering.
          example: 2
        passFrom:
          type:
            - string
            - 'null'
          description: |
            The minimum value that is required to pass this component within one offering. 
            This value is inclusive and depends on the resultValueType.
          example: '5.5'
        state:
          oneOf:
            - $ref: '#/components/schemas/componentState'
            - type: 'null'
        description:
          type:
            - array
            - 'null'
          description: The description of this component.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: |
                'Prove executable knowledge of research methods, including: Acquire knowledge of HCI research paradigms Able to design suitable research studies (e.g., choose between within and between subject designs) Define/apply/design metrics and scales Define/produce materials (e.g., stimuli and questionnaires) Define protocols for research studies Understands and take in account concepts of reliability and validity Analyse and improve methods and analysis of published scientific articles Able to deliver scientific reports
                Prove executable knowledge of statistics, including: Handle hypothesis testing with complex designs (e.g., including , dependent, independent, and co variates) Data preparation (e.g., coding and feature selection) Reason towards adequate techniques to ensure valid outcomes (e.g., be aware of type I, type II errors) Select an appropriate sampling method (e.g., stratified) Perform parametric tests (e.g., repeated measures (M)ANOVA) Perform non-parametric tests (e.g., Chi-square, Mann-Whitney, and Kruskal-Wallis)'
        teachingLanguages:
          type:
            - array
            - 'null'
          description: The languages in which this test component is given, should be three-letter language codes as specified by ISO 639-2. A student should be reasonably proficient in each language to be able to follow the test component.
          minItems: 1
          items:
            $ref: '#/components/schemas/Language'
        learningOutcomeIds:
          description: |
            The identifiers of the learning outcomes related to this test component.
            When the client does not request expansion of `learningOutcomes`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        learningOutcomes:
          description: |
            The expanded learning outcome objects related to this test component.
            When the client requests expansion of `learningOutcomes`, the full learning outcome objects MUST be returned here instead of only the identifiers.
            If no learning outcomes are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/LearningOutcome'
            title: LearningOutcome
        enrolment:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          description: The extra information that is provided for enrolment
          example:
            - language: en-GB
              value: enrolment through SIS. [The limited implementation of Git Hub Markdown syntax](https://openonderwijsapi.nl/v6.0/#/technical/formatting-text) MAY be used for rich text representation.
        resources:
          type:
            - array
            - 'null'
          description: An overview of the literature and other resources that are allowed during this test
          items:
            type: string
          example:
            - Scientific calculator
            - Criminal code law book
        assessment:
          type:
            - array
            - 'null'
          description: A description of the way this test is taken.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Exam on campus
        addresses:
          type:
            - array
            - 'null'
          description: Addresses for this component
          items:
            $ref: '#/components/schemas/Address'
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
        parentId:
          description: |
            The identifier of the parent Test Component of which the current Test Component is a child.
            When the client does not request expansion of `parent`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        parent:
          description: |
            The expanded parent Test Component of which the current Test Component is a child.
            When the client requests expansion of `parent`, the full Test Component object MUST be returned here instead of only the identifier.
            If no parent is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/TestComponent'
        childIds:
          description: |
            The identifiers of the Test Components that are part of this Test Component.
            When the client does not request expansion of `children`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).

            Although `childIds` and `children` (for example `organisationIds` versus `organisations`) may 
            seem unusual, this naming is intentional and follows the singular–plural convention defined 
            by the specification.
          type: array
          items:
            $ref: '#/components/schemas/Identifier'
        children:
          description: |
            The expanded Test Components that are part of this Test Component (e.g. combined tests).
            When the client requests expansion of `children`, the full Test Component objects MUST be returned here instead of only the identifiers.
          type: array
          items:
            $ref: '#/components/schemas/TestComponent'
            title: Expanded TestComponent
        courseId:
          description: |
            The identifier of the course of which this component is a part.
            When the client does not request expansion of `course`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        course:
          description: |
            The expanded course object of which this component is a part.
            When the client requests expansion of `course`, the full course object MUST be returned here instead of only the identifier.
            If no course is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Course'
          title: Course object
        organisationId:
          description: |
            The identifier of the organisation which provides this component.
            When the client does not request expansion of `organisation`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        organisation:
          description: |
            The expanded organisation object which provides this component.
            When the client requests expansion of `organisation`, the full organisation object MUST be returned here instead of only the identifier.
            If no organisation is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Organisation'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    LearningComponentOffering:
      allOf:
        - $ref: '#/components/schemas/LearningComponentOfferingId'
        - $ref: '#/components/schemas/OfferingProperties'
        - type: object
          description: |
            startDateTime and endDateTime of an offering are to be provided at least in the state `active`. In all other states the
            times on the academic session should indicate in what timeframe the offering will or should have been available.
          properties:
            startDateTime:
              type:
                - string
                - 'null'
              description: The moment on which this offering starts, RFC3339 (date-time)
              format: date-time
              example: '2020-12-15T10:00:00+01:00'
            endDateTime:
              type:
                - string
                - 'null'
              description: The moment on which this offering ends, RFC3339 (date-time)
              format: date-time
              example: '2020-12-16T18:00:00+01:00'
            resultWeight:
              type:
                - integer
                - 'null'
              description: The result weight of this offering
              minimum: 0
              maximum: 100
              example: 100
            addresses:
              type:
                - array
                - 'null'
              description: Addresses for this offering
              items:
                $ref: '#/components/schemas/Address'
            priceInformation:
              type:
                - array
                - 'null'
              description: Price information for this offering.
              items:
                $ref: '#/components/schemas/Cost'
            roomIds:
              description: |
                The identifiers of the rooms for this offering.
                When the client does not request expansion of `rooms`, only these identifiers are returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/Identifier'
            rooms:
              description: |
                The expanded room objects for this offering. 
                When the client requests expansion of `rooms`, the full expanded room objects MUST be returned here instead of only the identifiers. 
                If no rooms are defined, this value is `null`.
              type:
                - array
                - 'null'
              items:
                type:
                  - object
                  - 'null'
                allOf:
                  - $ref: '#/components/schemas/Room'
            learningComponentId:
              description: |
                The identifier of the learningComponent that is offered in this learningComponent offering.
                When the client does not request expansion of `learningComponent`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            learningComponent:
              description: |
                The expanded learningComponent object that is offered in this learningComponent offering.
                When the client requests expansion of `learningComponent`, the full expanded learningComponent object MUST be returned here instead of only the identifier.
                If no learningComponent is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/LearningComponent'
            courseOfferingIds:
              description: |
                The identifiers of the courseOfferings to which this learningComponent offering is related.
                When the client does not request expansion of `courseOfferings`, only these identifiers are returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/Identifier'
            courseOfferings:
              description: |
                The expanded courseOffering objects to which this learningComponent offering is related.
                When the client requests expansion of `courseOfferings`, the full expanded courseOffering objects MUST be returned here instead of only the identifiers.
                If no courseOfferings are defined, this value is `null`.
              type:
                - array
                - 'null'
              items:
                type:
                  - object
                  - 'null'
                allOf:
                  - $ref: '#/components/schemas/CourseOffering'
            organisationId:
              description: |
                The identifier of the organisation that manages this component offering.
                When the client does not request expansion of `organisation`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            organisation:
              description: |
                The expanded organisation object that manages this component offering.
                When the client requests expansion of `organisation`, the full expanded organisation object MUST be returned here instead of only the identifier.
                If no organisation is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Organisation'
    LearningComponentOfferingAssociation:
      allOf:
        - $ref: '#/components/schemas/AssociationId'
        - $ref: '#/components/schemas/AssociationProperties'
        - type: object
          anyOf:
            - required:
                - personId
                - learningComponentOfferingId
            - title: With expanded learning component offering
              required:
                - personId
                - learningComponentOffering
            - title: With expanded person
              required:
                - person
                - learningComponentOfferingId
            - title: With expanded person and learning component offering
              required:
                - person
                - learningComponentOffering
          properties:
            result:
              oneOf:
                - $ref: '#/components/schemas/LearningComponentOfferingAssociationResult'
            attendance:
              oneOf:
                - $ref: '#/components/schemas/associationAttendance'
                - type: 'null'
            personId:
              description: |
                The identifier of the person referenced here.
                When the client does not request expansion of `person`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            person:
              description: |
                The expanded person object referenced here.
                When the client requests expansion of `person`, the full expanded person object MUST be returned here instead of only the identifier.
                If no person is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Person'
            learningComponentOfferingId:
              description: |
                The identifier of the learningComponentOffering referenced here.
                When the client does not request expansion of `offering`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            learningComponentOffering:
              description: |
                The expanded learningComponentOffering object referenced here.
                When the client requests expansion of `offering`, the full expanded learningComponentOffering object MUST be returned here instead of only the identifier.
                If no offering is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/LearningComponentOffering'
    TestComponentOffering:
      allOf:
        - $ref: '#/components/schemas/TestComponentOfferingId'
        - $ref: '#/components/schemas/OfferingProperties'
        - type: object
          description: |
            startDateTime and endDateTime of an offering must be provided at least in the state `active`. In all other states the
            times on the academic session should indicate in what timeframe the offering will or should have been available.
          properties:
            startDateTime:
              type:
                - string
                - 'null'
              description: The moment on which this offering starts, RFC3339 (date-time)
              format: date-time
              example: '2025-03-01T08:30:00+01:00'
            endDateTime:
              type:
                - string
                - 'null'
              description: The moment on which this offering ends, RFC3339 (date-time)
              format: date-time
              example: '2025-07-19T08:30:00+01:00'
            resultWeight:
              type:
                - integer
                - 'null'
              description: The result weight of this offering
              minimum: 0
              maximum: 100
              example: 100
            addresses:
              type:
                - array
                - 'null'
              description: Addresses for this offering
              items:
                $ref: '#/components/schemas/Address'
            priceInformation:
              type:
                - array
                - 'null'
              description: Price information for this offering.
              items:
                $ref: '#/components/schemas/Cost'
            roomIds:
              description: |
                The identifiers of the rooms for this offering.
                When the client does not request expansion of `rooms`, only these identifiers are returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/Identifier'
            rooms:
              description: |
                The expanded room objects for this offering. 
                When the client requests expansion of `rooms`, the full expanded room objects MUST be returned here instead of only the identifiers. 
                If no rooms are defined, this value is `null`.
              type:
                - array
                - 'null'
              items:
                type:
                  - object
                  - 'null'
                allOf:
                  - $ref: '#/components/schemas/Room'
            componentId:
              description: |
                The identifier of the component that is offered in this component offering.
                When the client does not request expansion of `component`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            component:
              description: |
                The expanded component that is offered in this component offering.
                When the client requests expansion of `component`, the full component object MUST be returned here instead of only the identifier.
                If no component is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/TestComponent'
            courseOfferingIds:
              description: |
                The identifiers of the course offerings to which this test component offering is related.
                When the client does not request expansion of `courseOfferings`, only these identifiers are returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/Identifier'
                title: courseOfferingId
            courseOfferings:
              description: |
                The expanded course offering objects to which this test component offering is related.
                When the client requests expansion of `courseOfferings`, the full course offering objects MUST be returned here instead of only the identifiers.
                If no course offerings are defined, this value is `null`.
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/CourseOffering'
            organisationId:
              description: |
                The identifier of the organisation that manages this component offering.
                When the client does not request expansion of `organisation`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            organisation:
              description: |
                The expanded organisation object that manages this component offering.
                When the client requests expansion of `organisation`, the full organisation object MUST be returned here instead of only the identifier.
                If no organisation is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Organisation'
            documents:
              type:
                - array
                - 'null'
              description: |
                Documents that are related to the test component offering. E.g. instructions, assignment, reports, etc.
              items:
                type: object
                required:
                  - documentId
                  - documentType
                  - documentName
                properties:
                  documentId:
                    type: string
                    description: The unique identifier of the document
                    example: 12345678-1234-1234-1234-123456789012
                  documentType:
                    $ref: '#/components/schemas/documentType'
                  documentName:
                    type: string
                    description: The name of the document
                    example: Assignment 1.pdf
    TestComponentOfferingAssociation:
      allOf:
        - $ref: '#/components/schemas/AssociationId'
        - $ref: '#/components/schemas/AssociationProperties'
        - type: object
          anyOf:
            - required:
                - personId
                - testComponentOfferingId
            - title: With expanded test component offering
              required:
                - personId
                - testComponentOffering
            - title: With expanded person
              required:
                - person
                - testComponentOfferingId
            - title: With expanded test component offering and person
              required:
                - person
                - testComponentOffering
          properties:
            extraDuration:
              type:
                - string
                - 'null'
              description: The extra duration of this component for this specific candidate. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339.
              pattern: ^-?P(?:\d+Y)?(?:\d+M)?(?:\d+(?:D|W))?(?:T(?:\d+H)?(?:\d+M)?(?:\d+(?:\.\d+)?S)?)?$
              example: PT20M
            requiredPersonalNeeds:
              type:
                - array
                - 'null'
              description: The additional facilities or resources needed by a person to make the component accessible and usable.
              items:
                $ref: '#/components/schemas/personalNeed'
            attempt:
              type:
                - integer
                - 'null'
              description: The attempt this association is linked to.
              example: 2
            attendance:
              oneOf:
                - $ref: '#/components/schemas/associationAttendance'
                - type: 'null'
            irregularities:
              type:
                - array
                - 'null'
              description: The irregularities that are reported for this association. This is a list of the irregularities that are reported for this association.
              items:
                type: string
            documents:
              type:
                - array
                - 'null'
              description: |
                Documents that are related to the test component offering association. E.g. handed in documents, plagiarism reports, test made, etc.
              items:
                $ref: '#/components/schemas/Document'
            result:
              oneOf:
                - $ref: '#/components/schemas/TestComponentOfferingAssociationResult'
                - type: 'null'
            personId:
              description: |
                The identifier of the person referenced here.
                When the client does not request expansion of `person`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            person:
              description: |
                The expanded person object referenced here.
                When the client requests expansion of `person`, the full person object MUST be returned here instead of only the identifier.
                If no person is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Person'
              title: Person
            testComponentOfferingId:
              description: |
                The identifier of the testComponentOffering referenced here.
                When the client does not request expansion of `offering`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            testComponentOffering:
              description: |
                The expanded testComponentOffering object referenced here.
                When the client requests expansion of `testComponentOffering`, the full TestComponentOffering object MUST be returned here instead of only the identifier.
                If no testComponentOffering is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/TestComponentOffering'
            attemptIds:
              description: |
                The identifiers of the attempts related to this testComponentOffering association.
                When the client does not request expansion of `attempts`, only these identifiers are returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/Identifier'
                title: attemptId
            attempts:
              description: |
                The expanded attempt objects related to this testComponentOffering association.
                When the client requests expansion of `attempts`, the full TestComponentOfferingAssociationAttempt objects MUST be returned here instead of only the identifiers.
                If no attempts are defined, this value is `null`.
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/TestComponentOfferingAssociationAttempt'
    Course:
      allOf:
        - $ref: '#/components/schemas/CourseId'
        - $ref: '#/components/schemas/CourseProperties'
        - type: object
          properties:
            validFrom:
              description: The first day and time this course is valid (inclusive).
              type:
                - string
                - 'null'
              format: date-time
              example: '2025-09-01T09:00:00+01:00'
            validTo:
              description: The day and time this course ceases to be valid (e.g. exclusive).
              type:
                - string
                - 'null'
              format: date-time
              example: '2025-09-01T09:00:00+01:00'
    CourseOffering:
      allOf:
        - $ref: '#/components/schemas/CourseOfferingId'
        - $ref: '#/components/schemas/OfferingProperties'
        - type: object
          description: |
            startDateTime and endDateTime of an offering are to be provided at least in the state `active`. In all other states the
            times on the academic session should indicate in what timeframe the offering will or should have been available.
          title: CourseOffering
          properties:
            startDateTime:
              type:
                - string
                - 'null'
              description: The moment on which this offering starts, RFC3339 (date-time)
              format: date-time
              example: '2019-08-21T08:30:00+01:00'
            endDateTime:
              type:
                - string
                - 'null'
              description: The moment on which this offering ends, RFC3339 (date-time)
              format: date-time
              example: '2019-10-23T22:59:59+01:00'
            flexibleEntryPeriodStartDateTime:
              type:
                - string
                - 'null'
              description: |
                Use this attribute for courses that allow participants who have already
                enrolled to begin their participation at different moments without
                missing essential content. This attribute MUST be used in combination
                with `flexibleEntryPeriodEndDateTime`.
              format: date-time
              example: '2019-08-21T09:00:00+01:00'
            flexibleEntryPeriodEndDateTime:
              type:
                - string
                - 'null'
              description: |
                If this is a course wherein participants who have already enrolled can
                start at various moments without missing any essential content, use this
                attribute in combination with `flexibleEntryPeriodStartDateTime`.
              format: date
              example: '2019-10-21T22:59:59+01:00'
            addresses:
              type:
                - array
                - 'null'
              description: Addresses for this offering
              items:
                $ref: '#/components/schemas/Address'
            priceInformation:
              type:
                - array
                - 'null'
              description: Price information for this offering.
              items:
                $ref: '#/components/schemas/Cost'
            courseId:
              description: |
                The identifier of the course that is offered in this course offering.
                When the client does not request expansion of `course`, only this
                identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            course:
              description: |
                The expanded course object that is offered in this course offering.
                When the client requests expansion of `course`, the full expanded
                course object MUST be returned here instead of only the identifier.
                If no course is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Course'
            programmeOfferingIds:
              description: |
                An array of 0 or more identifiers of programmeOfferings that this
                course offering is related to.
                When the client does not request expansion of `programmeOfferings`,
                only these identifiers are returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/Identifier'
            programmeOfferings:
              description: |
                An array of 0 or more expanded programmeOffering objects that this
                course offering is related to.
                When the client requests expansion of `programmeOfferings`, the full
                expanded programmeOffering objects MUST be returned here instead of
                only the identifiers.
                If no programmeOfferings are defined, this value is `null`.
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/ProgrammeOffering'
            organisationId:
              description: |
                The identifier of the organisation that manages this course offering.
                When the client does not request expansion of `organisation`, only this
                identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            organisation:
              description: |
                The expanded organisation object that manages this course offering.
                When the client requests expansion of `organisation`, the full expanded
                organisation object MUST be returned here instead of only the identifier.
                If no organisation is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Organisation'
    CourseOfferingAssociation:
      allOf:
        - $ref: '#/components/schemas/AssociationId'
        - $ref: '#/components/schemas/AssociationProperties'
        - type: object
          anyOf:
            - required:
                - courseOfferingId
                - personId
            - title: With expanded person
              required:
                - courseOfferingId
                - person
            - title: With expanded course offering and person
              required:
                - courseOffering
                - person
            - title: With expanded course offering
              required:
                - courseOffering
                - personId
          properties:
            studyLoad:
              description: |
                Only required when the studyload for the individual student/enrolment is different 
                from the studyload of the course offering.
              oneOf:
                - $ref: '#/components/schemas/StudyLoadDescriptor'
                - type: 'null'
            result:
              oneOf:
                - $ref: '#/components/schemas/CourseOfferingAssociationResult'
                - type: 'null'
            courseOfferingId:
              description: |
                The identifier of the courseOffering referenced here.
                When the client or server does not expand `offering`, only this
                identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            courseOffering:
              description: |
                The expanded courseOffering object referenced here.
                When the client or server expands `offering`, the full expanded
                courseOffering object MUST be returned here instead of only the
                identifier.
                If no offering is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/CourseOffering'
            personId:
              description: |
                The identifier of the person referenced here.
                When the client or server does not expand `person`, only this
                identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            person:
              description: |
                The expanded person object referenced here.
                When the client or server expands `person`, the full expanded
                person object MUST be returned here instead of only the identifier.
                If no person is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Person'
    Group:
      allOf:
        - $ref: '#/components/schemas/GroupId'
        - type: object
          description: |
            A group is simply a collection of persons. Groups can be used to accommodate various use cases.
            Groups MAY optionally have a relation to an offering, however the meaning of such relations is left unspecified and is left up to the implementer.
          required:
            - groupType
            - name
            - primaryCode
          properties:
            primaryCode:
              description: The primary human readable identifier for this group. This is often the source identifier as defined by the institution.
              $ref: '#/components/schemas/IdentifierEntry'
              example:
                codeType: groupCode
                code: group-abc987
            groupType:
              $ref: '#/components/schemas/groupType'
            name:
              type: array
              description: The name of this group
              minItems: 1
              items:
                $ref: '#/components/schemas/LanguageTypedString'
              example:
                - language: en-GB
                  value: statistics students
            description:
              type:
                - array
                - 'null'
              description: The description of this group
              minItems: 1
              items:
                $ref: '#/components/schemas/LanguageTypedString'
              example:
                - language: en-GB
                  value: The group of students that follow statistics classes
            startDateTime:
              type:
                - string
                - 'null'
              description: |
                The moment on which this group starts being active, RFC3339 (date-time).
                Groups can be ordered in time through the academicSession. The start and 
                end date and time fields SHOULD always contain the most accurate dates.
              format: date-time
              example: '2025-05-30T20:00:00+01:00'
            endDateTime:
              type:
                - string
                - 'null'
              description: |
                The moment on which this group ends being active, RFC3339 (date-time)
                Groups can be ordered in time through the academicSession. The start and 
                end date and time fields SHOULD always contain the most accurate dates.
              format: date-time
              example: '2025-06-30T20:00:00+01:00'
            personCount:
              type:
                - number
                - 'null'
              description: The number of persons that are member of this group
              format: int32
              minimum: 0
              example: 183
            otherCodes:
              type:
                - array
                - 'null'
              description: An array of additional human readable codes/identifiers for the entity being described.
              items:
                $ref: '#/components/schemas/IdentifierEntry'
            consumer:
              oneOf:
                - $ref: '#/components/schemas/Consumer'
                - type: 'null'
            organisationId:
              description: |
                The identifier of the organisation that manages this group.
                When the client does not request expansion of `organisation`, only this
                identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            organisation:
              description: |
                The expanded organisation object that manages this group.
                When the client requests expansion of `organisation`, the full expanded
                organisation object MUST be returned here instead of only the identifier.
                If no organisation is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Organisation'
            academicSessionId:
              description: |
                The identifier of the academicSession for which this group is intended.
                When the client does not request expansion of `academicSession`, only this
                identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            academicSession:
              description: |
                The expanded academicSession object for which this group is intended.
                When the client requests expansion of `academicSession`, the full expanded
                academicSession object MUST be returned here instead of only the identifier.
                If no academicSession is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/AcademicSession'
            offeringIds:
              description: |
                The offering identifiers (0..N) associated with this group.
              oneOf:
                - type: array
                  items:
                    type: object
                    minProperties: 1
                    maxProperties: 1
                    additionalProperties: false
                    properties:
                      courseOfferingId:
                        $ref: '#/components/schemas/courseOfferingId'
                      programmeOfferingId:
                        $ref: '#/components/schemas/programmeOfferingId'
                      learningComponentOfferingId:
                        $ref: '#/components/schemas/learningComponentOfferingId'
                      testComponentOfferingId:
                        $ref: '#/components/schemas/testComponentOfferingId'
                - type: 'null'
            ext:
              oneOf:
                - $ref: '#/components/schemas/Ext'
                - type: 'null'
    Membership:
      type: object
      description: A membership contains the information on a membership of a person for a specific group
      required:
        - personId
        - groupId
        - role
        - state
      properties:
        personId:
          type: string
          description: Unique id for this membership (this is the personID since there is a 1-1 relationship between membership of a group and a person) item
          format: uuid
          example: 123e4567-e89b-12d3-a456-122564174000
        groupId:
          type: string
          description: Id for the group where the person has a membership
          format: uuid
          example: 123e4567-e89b-12d3-a456-122564174000
        startDateTime:
          type:
            - string
            - 'null'
          description: The moment from which the person participates in this membership, RFC3339 (date-time)
          format: date-time
          example: '2020-09-28T08:30:00+01:00'
        endDateTime:
          type:
            - string
            - 'null'
          description: The moment until which this person participates in this membership (when the membership stops), RFC3339 (date-time)
          format: date-time
          example: '2020-09-30T20:00:00+01:00'
        state:
          $ref: '#/components/schemas/membershipState'
        role:
          $ref: '#/components/schemas/membershipRole'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    LearningOutcome:
      type: object
      description: statements regarding what a learner knows, understands and is able to do on completion of a learning process, which are defined in terms of knowledge, skills and responsibility and autonomy (https://eur-lex.europa.eu/legal-content/EN/TXT/PDF/?uri=CELEX:32017H0615(01)&from=EN)
      required:
        - learningOutcomeId
        - primaryCode
        - name
      properties:
        learningOutcomeId:
          type: string
          description: Unique id of this learning outcome
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        primaryCode:
          description: The primary human readable identifier for this learning outcome. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: learningOutcomeCode
            code: LO 2.1
        name:
          type: array
          description: The name of this learning outcome
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: |
                Describe the differing views, within society, relating to the scientific uses of animals and recognize the need to respect these.
        abbreviation:
          type:
            - string
            - 'null'
          description: The abbreviation or internal code used to identify this LearningOutcome
          maxLength: 256
          example: LO12_INFO_RET
        description:
          type:
            - array
            - 'null'
          description: The description of this learning outcome.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: |
                The candidate should have retained the information that they
                have been taught and be able to:
                1. Relate opinions as voiced collectively or individually by:
                  * animal protection societies
                  * patient support societies
                  * establishments and researchers
                  * industry, including pharma, biotech and food
                  * people with personal, cultural or religious beliefs;
                2. Recognize the fundamental right of freedom of speech;
                3. Recall different perspectives which enable an individual to
                  determine their own opinion on the use of animals for scientific
                  purposes;
                4. Explain how different perspectives drive forward advancements
                  in animal welfare, legislation and science.
                (based on: https://repub.eur.nl/pub/132564/Repub_132564_O-A.pdf)
        parentIds:
          description: |
            The identifiers of the learning outcomes which are the parents of this learning outcome.
            When the client does not request expansion of `parents`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        parents:
          description: |
            The expanded learning outcome objects which are the parents of this learning outcome.
            When the client requests expansion of `parents`, the full expanded learning outcome objects MUST be returned here instead of only the identifiers.
            If no parents are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            type:
              - object
              - 'null'
            allOf:
              - $ref: '#/components/schemas/LearningOutcome'
        childIds:
          description: |
            The identifiers of all learning outcomes for which this learning outcome is the parent.
            When the client does not request expansion of `children`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).

            Although `childIds` and `children` (for example `organisationIds` versus `organisations`) may 
            seem unusual, this naming is intentional and follows the singular–plural convention defined 
            by the specification.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        children:
          description: |
            The expanded learning outcome objects for which this learning outcome is the parent.
            When the client requests expansion of `children`, the full expanded learning outcome objects MUST be returned here instead of only the identifiers.
            If no children are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            type:
              - object
              - 'null'
            allOf:
              - $ref: '#/components/schemas/LearningOutcome'
        fieldsOfStudy:
          type:
            - string
            - 'null'
          description: |
            Field(s) of study (e.g. ISCED-F) (https://unesdoc.unesco.org/ark:/48223/pf0000228085.locale=en). 
            ISCED-F categorizes the fields of study 2 digits at root level and further subdivision as more digits are added.
            Preferably fieldsOfStudy contains at least 4 digits.
            ISCEDF2013vSOI2021 currently allows for 6 digits max (https://www.cbs.nl/-/media/cbs/onze-diensten/methoden/classificaties/documents/2025/pubsoi2021_ed2425.pdf).
            07 Engineering, manufacturing and construction
            073 Architecture and construction
            0731 Architecture and town planning
            073101 Town planning
          minLength: 2
          maxLength: 6
          example: '0732'
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
        complexityLevel:
          oneOf:
            - $ref: '#/components/schemas/learningOutcomeLevel'
            - type: 'null'
        validFrom:
          type:
            - string
            - 'null'
          description: The date and time for when this learning outcome will be active. Should be a string formatted as an RFC3099 full-date.
          format: date-time
          example: '2025-09-01T09:00:00+01:00'
        validTo:
          type:
            - string
            - 'null'
          description: The date and time when this learning outcome will no longer be valid, or should be renewed. Should be a string formatted as an RFC3099 full-date.
          format: date-time
          example: '2025-09-01T09:00:00+01:00'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    Organisation:
      type: object
      description: A description of a group of people working together to achieve a goal
      required:
        - organisationId
        - organisationType
        - name
        - primaryCode
      properties:
        organisationId:
          type: string
          description: Unique id of this organisation
          format: uuid
          example: 123e4567-e89b-12d3-a456-123514174000
        primaryCode:
          description: The primary human readable identifier for the organisation. This is often the source identifier as defined by the root organisation.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: organisation_id
            code: Org01-Root
        organisationType:
          $ref: '#/components/schemas/organisationType'
        name:
          type: array
          description: The name of the organisation
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: nl-NL
              value: Coöperatie SURF U.A.
        shortName:
          type:
            - string
            - 'null'
          description: Short name of the organisation
          maxLength: 256
          example: SURF
        description:
          type:
            - array
            - 'null'
          description: |
            If the organisation is an educational organisation, any general description should clearly mention the type of 
            education organisation, especially in the case of a binary system. In Dutch; universiteit (university) or 
            hogeschool (university of applied sciences).
            If the organisation is not an educational organisation, a general description should describe the role it plays 
            in education like providing certain types of internships, educational services, products or facilities.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: nl-NL
              value: SURF is een coöperatieve vereniging van Nederlandse onderwijs- en onderzoeksinstellingen waarin de leden hun krachten bundelen. De leden zijn eigenaar van SURF.
        addresses:
          type:
            - array
            - 'null'
          description: Addresses of this organisation
          items:
            $ref: '#/components/schemas/Address'
        link:
          type:
            - string
            - 'null'
          description: URL of the organisation's website
          format: uri
          maxLength: 2048
          example: https://surf.nl
        logo:
          type:
            - string
            - 'null'
          description: Logo of this organisation
          format: uri
          maxLength: 2048
          example: https://www.surf.nl/themes/surf/logo.svg
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
          example:
            - codeType: institution_code
              code: 114B529
            - codeType: kvk_organisation_id
              code: '50277374'
        rootId:
          description: |
            The identifier of the organisation which is the root organisation of this organisation.
            When the client does not request expansion of `root`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        root:
          description: |
            The expanded organisation object which is the root organisation of this organisation.
            When the client requests expansion of `root`, the full expanded organisation object MUST be returned here instead of only the identifier.
            If no root organisation is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Organisation'
        parentId:
          description: |
            The identifier of the organisational unit which is the parent of this organisation.
            When the client does not request expansion of `parent`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        parent:
          description: |
            The expanded organisation object which is the parent of this organisation.
            When the client requests expansion of `parent`, the full expanded organisation object MUST be returned here instead of only the identifier.
            If no parent organisation is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Organisation'
        childIds:
          description: |
            The identifiers of the organisational units for which this organisation is the parent.
            When the client does not request expansion of `children`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).

            Although `childIds` and `children` (for example `organisationIds` versus `organisations`) may 
            seem unusual, this naming is intentional and follows the singular–plural convention defined 
            by the specification.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        children:
          description: |
            The expanded organisational unit objects for which this organisation is the parent.
            When the client requests expansion of `children`, the full expanded organisation objects MUST be returned here instead of only the identifiers.
            If no children are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            type:
              - object
              - 'null'
            allOf:
              - $ref: '#/components/schemas/Organisation'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    Person:
      allOf:
        - $ref: '#/components/schemas/PersonId'
        - $ref: '#/components/schemas/PersonProperties'
    Programme:
      allOf:
        - $ref: '#/components/schemas/ProgrammeId'
        - $ref: '#/components/schemas/ProgrammeProperties'
        - type: object
          properties:
            validFrom:
              description: The first moment this programme is valid (inclusive).
              type:
                - string
                - 'null'
              format: date-time
              example: '2025-09-01T09:00:00+01:00'
            validTo:
              description: The moment this programme ceases to be valid (e.g. exclusive).
              type:
                - string
                - 'null'
              format: date-time
              example: '2025-09-01T09:00:00+01:00'
    ProgrammeOffering:
      allOf:
        - $ref: '#/components/schemas/ProgrammeOfferingId'
        - $ref: '#/components/schemas/OfferingProperties'
        - type: object
          description: A programme offering which describes the programme in time.
          title: ProgrammeOffering
          properties:
            startDateTime:
              type:
                - string
                - 'null'
              description: The moment on which this offering starts, RFC3339 (date-time)
              format: date-time
              example: '2025-09-28T08:30:00+01:00'
            endDateTime:
              type:
                - string
                - 'null'
              description: The moment on which this offering ends, RFC3339 (date-time)
              format: date-time
              example: '2025-12-28T08:30:00+01:00'
            flexibleEntryPeriodStartDateTime:
              type:
                - string
                - 'null'
              description: |
                Use this attribute for courses that allow participants who have already
                enrolled to begin their participation at different moments without
                missing essential content. This attribute MUST be used in combination
                with `flexibleEntryPeriodEndDateTime`.
              format: date-time
              example: '2019-08-21T09:00:00+01:00'
            flexibleEntryPeriodEndDateTime:
              type:
                - string
                - 'null'
              description: |
                If this is a course wherein participants who have enrolled can start at
                various moments without missing anything, use this attribute in
                combination with `flexibleEntryPeriodStartDateTime`.
              format: date-time
              example: '2019-10-21T22:59:59+01:00'
            addresses:
              type:
                - array
                - 'null'
              description: Addresses for this offering
              items:
                $ref: '#/components/schemas/Address'
            priceInformation:
              type:
                - array
                - 'null'
              description: Price information for this offering.
              items:
                $ref: '#/components/schemas/Cost'
              minItems: 1
            programmeId:
              description: |
                The identifier of the programme that is offered in this programmeOffering.
                When the client does not request expansion of `programme`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            programme:
              description: |
                The expanded programme object that is offered in this programmeOffering.
                When the client requests expansion of `programme`, the full expanded programme object MUST be returned here instead of only the identifier.
                If no programme is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Programme'
            organisationId:
              description: |
                The identifier of the organisation that manages this programmeOffering.
                When the client does not request expansion of `organisation`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            organisation:
              description: |
                The expanded organisation object that manages this programmeOffering.
                When the client requests expansion of `organisation`, the full expanded organisation object MUST be returned here instead of only the identifier.
                If no organisation is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Organisation'
    Room:
      type: object
      description: An area within a building where education can take place
      required:
        - roomId
        - roomType
        - name
        - primaryCode
      properties:
        roomId:
          type: string
          description: Unique id for this room
          format: uuid
          example: 123e4567-e89b-12d3-a456-332114174000
        primaryCode:
          description: The primary human readable identifier for the room. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: roomCode
            code: Bb4.54
        roomType:
          $ref: '#/components/schemas/roomType'
        abbreviation:
          type:
            - string
            - 'null'
          description: The abbreviation of the name of this room
          maxLength: 256
          example: Bb4.54
        name:
          type: array
          description: The name of this room
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Beatrix building room 4.54
        description:
          type:
            - array
            - 'null'
          description: The description of this room. [The limited implementation of Git Hub Markdown syntax](https://openonderwijsapi.nl/v6.0/#/technical/formatting-text) MAY be used for rich text representation.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: External education and exam room 4.54
        totalSeats:
          type:
            - integer
            - 'null'
          format: int32
          description: The total number of seats located in the room
          example: 300
        availableSeats:
          type:
            - integer
            - 'null'
          format: int32
          description: The total number of available (=non-reserved) seats in the room
          example: 200
        floor:
          type:
            - string
            - 'null'
          description: The floor on which this room is located
          example: '4'
        wing:
          type:
            - string
            - 'null'
          description: The wing in which this room is located
          example: None
        geolocation:
          type:
            - object
            - 'null'
          description: Geolocation of the entrance of this room (WGS84 coordinate reference system)
          required:
            - latitude
            - longitude
          properties:
            latitude:
              type: number
              format: double
              example: 52.088255
            longitude:
              type: number
              format: double
              example: 5.106669
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
        buildingId:
          description: |
            The identifier of the building in which the room is located.
            When the client does not request expansion of `building`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        building:
          description: |
            The expanded building object in which the room is located.
            When the client requests expansion of `building`, the full building object MUST be returned here instead of only the identifier.
            If no building is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Building'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    ProgrammeOfferingAssociation:
      allOf:
        - $ref: '#/components/schemas/ProgrammeOfferingAssociationExternalMe'
        - type: object
          anyOf:
            - required:
                - programmeOfferingId
                - personId
            - title: With expanded person
              required:
                - programmeOfferingId
                - person
            - title: With expanded programme offering and person
              required:
                - programmeOffering
                - person
            - title: With expanded programme offering
              required:
                - programmeOffering
                - personId
          properties:
            personId:
              description: |
                The identifier of the person referenced here.
                When the client does not request expansion of `person`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              readOnly: true
              $ref: '#/components/schemas/Identifier'
            person:
              description: |
                The expanded person object referenced here.
                When the client requests expansion of `person`, the full expanded person object MUST be returned here instead of only the identifier.
                If no person is defined, this value is `null`.
              readOnly: true
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/Person'
            programmeOfferingId:
              description: |
                The identifier of the `programmeOffering` referenced here.
                When the client does not request expansion of `offering`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            programmeOffering:
              description: |
                The expanded programmeOffering object referenced here.
                When the client requests expansion of `offering`, the full expanded programmeOffering object MUST be returned here instead of only the identifier.
                If no offering is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/ProgrammeOffering'
    TestComponentOfferingAssociationAttempt:
      type: object
      description: |
        Planning and execution information on an attempt belong to a TestComponentOfferingAssociation. Result on the attempt
        is only relevant when a score or rawScore can be determined.
      required:
        - attemptId
      properties:
        attemptId:
          type: string
          description: Unique id of this attempt
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
        opportunity:
          type:
            - string
            - 'null'
          description: |
            The opportunity during which this attempt can be fulfilled. 
            Only relevant when only one attempt is allowed per association.
          example: 2025Semester1
        attempt:
          type:
            - integer
            - 'null'
          description: |
            Which attempt this is for the given person on the given offering.
          format: int32
          example: 1
        state:
          oneOf:
            - $ref: '#/components/schemas/attemptState'
            - type: 'null'
        startDateTime:
          type:
            - string
            - 'null'
          description: |
            Moment (date and time) of the start of the actual attempt. This can be the
            start date and time for an assessment where the association has no start or
            end date and time, but only has a relation with an academic session representing
            a term, trimester, semester or academic year.
          format: date-time
          example: '2025-09-01T09:00:00+01:00'
        endDateTime:
          type:
            - string
            - 'null'
          description: |
            Moment (date and time) of the end of the actual attempt. This can be the deadline 
            for handing in a document for an assignment or the end
            date and time for an test where the association has no start or
            end date and time, but only has a relation with an academic session representing
            a term, trimester, semester or academic year.
          format: date-time
          example: '2025-09-01T09:00:00+01:00'
        roomIds:
          description: |
            The identifiers of the rooms for this offering.
            When the client does not request expansion of `rooms`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        rooms:
          description: |
            The expanded room objects for this offering. 
            When the client requests expansion of `rooms`, the full expanded room objects MUST be returned here instead of only the identifiers. 
            If no rooms are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            type:
              - object
              - 'null'
            allOf:
              - $ref: '#/components/schemas/Room'
        attendance:
          oneOf:
            - $ref: '#/components/schemas/attendance'
            - type: 'null'
        irregularities:
          type:
            - string
            - 'null'
          description: |
            Additional information about external disturbances or (potentially) illegal actions by the student, 
            before, during or after the test.
          example: The student was late because there was a train delay
        coordinatorId:
          description: |
            The identifier of the coordinator responsible for overseeing the test.
            When the client does not request expansion of `coordinator`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        coordinator:
          description: |
            The expanded person object representing the coordinator responsible for overseeing the test.
            When the client requests expansion of `coordinator`, the full person object MUST be returned here instead of only the identifier.
            If no coordinator is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Person'
        documents:
          type:
            - array
            - 'null'
          description: |
            Documents that are related to the test component offering association attempt. E.g. test completed, work handed in, etc.
          items:
            $ref: '#/components/schemas/Document'
        result:
          oneOf:
            - $ref: '#/components/schemas/Result'
            - type: 'null'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
    expandableObjects:
      type: string
      description: |
        The object that can be expanded for this path.
          - academic_session: the academicSession object can be expanded.
          - building: the building object can be expanded.
          - child: the child object (which is an instance of the current object) can be expanded.
          - children: a set of objects (which are an instance of the current object) can be expanded.
          - coordinators: the person object indicating a coordinator can be expanded.
          - instructors: the person object indicating an instructor can be expanded.
          - course: the course object can be expanded.
          - course_offering: the courseOffering object can be expanded.
          - learning_component: the learningComponent object can be expanded.
          - learning_component_offering: the learningComponentOffering object can be expanded.
          - learning_outcome: the learningOutcome object can be expanded.
          - learning_outcomes: the learningOutcomes in the array containing learningOutcome objects can be expanded.
          - organisation: the organisation object can be expanded.
          - parent: the parent object (which is an instance of the current object) can be expanded.
          - person: the person object can be expanded.
          - programme: the programme object can be expanded.
          - programmes: the programmes in the array containing programme objects can be expanded.
          - programme_offering: the programmeOffering object can be expanded.
          - room: the room object can be expanded.
          - rooms: the rooms in the array can be expanded.
          - test_component: the testComponent object can be expanded.
          - test_component_offering: the testComponentOffering object can be expanded.
          - year: the academicSession object indicating the year can be expanded.
      x-ooapi-extensible-enum:
        - academic_session
        - building
        - child
        - children
        - coordinators
        - course
        - course_offering
        - instructors
        - learning_component
        - learning_component_offering
        - learning_outcome
        - learning_outcomes
        - organisation
        - parent
        - person
        - programme
        - programmes
        - programme_offering
        - room
        - rooms
        - test_component
        - test_component_offering
        - year
      example: programme
    Ext:
      type: object
      description: Object for additional non-standard attributes
    Problem:
      type: object
      description: |
        A problem details object, conforming to RFC 7807 (Problem Details for HTTP
        APIs). See https://datatracker.ietf.org/doc/html/rfc7807. It provides a
        machine-readable format for error conditions, including a type URI, title,
        status code, and optional detail and instance fields. This ensures
        consistent handling of error responses across the API.
      required:
        - type
        - status
        - title
      properties:
        type:
          type: string
          format: uri
          maxLength: 2048
          description: |
            An absolute URI that identifies the problem type. When dereferenced, 
            it should provide human-readable documentation.
          example: https://example.org/problems/bad-request
        title:
          type: string
          description: A short, human-readable summary of the problem type
          example: Resource not found
        status:
          type: integer
          format: int32
          description: |
            The HTTP status code generated by the origin server for this occurrence 
            of the problem.
          example: 404
        detail:
          type:
            - string
            - 'null'
          description: |
            A human-readable explanation specific to this occurrence of the problem
          example: The course with id 'abc123' could not be found in the catalogue.
        instance:
          type:
            - string
            - 'null'
          format: uri
          maxLength: 2048
          description: |
            An absolute URI that identifies the specific occurrence of the problem.
          example: https://api.example.org/courses/abc123
    type:
      type: string
      format: uri
      maxLength: 2048
      description: |
        An absolute URI that identifies the problem type. When dereferenced, 
        it should provide human-readable documentation.
      example: https://example.org/problems/bad-request
    title:
      type: string
      description: A short, human-readable summary of the problem type
      example: Resource not found
    Consumer:
      type: object
      description: The additional elements of a consumer that may be provided, see the [documentation on support for specific consumers](https://openonderwijsapi.nl/v6.0/#/technical/consumers-and-profiles/) for further information about this mechanism.
      required:
        - consumerKey
      properties:
        consumerKey:
          description: The key of the consumer (destination) for which this information is intended. See the [consumer registry](https://openonderwijsapi.nl/v6.0/#/technical/consumers-and-profiles/). This key is used to select the additional data to be presented in the request.
          type: string
          example: test-consumer
        exampleProperty:
          description: An example of an additional property
          type:
            - string
            - 'null'
          example: value-of-example-property
      additionalProperties: true
    ProblemVersionNotAcceptable:
      allOf:
        - $ref: '#/components/schemas/Problem'
        - type: object
          required:
            - requestedVersion
            - supportedVersions
          properties:
            type:
              $ref: '#/components/schemas/type'
            title:
              $ref: '#/components/schemas/title'
            consumer:
              description: |
                Indicates which party caused the version mismatch. When null, the 406 was
                triggered by an unsupported OOAPI version. If populated with a Consumer
                object, the 406 was caused by a consumer-specific version that did not match
                any supported version. This field MAY contain a full Consumer object or be
                null.
              oneOf:
                - $ref: '#/components/schemas/Consumer'
                - type: 'null'
            requestedVersion:
              type: string
              description: The version requested by the client.
              example: '5.0'
            supportedVersions:
              type: array
              description: Versions the server can serve, typically in descending order.
              items:
                type: string
              example:
                - '4.2'
                - '4.1'
    filterPresence:
      type: string
      description: |
        Presence check or special value for filter operations.

        Inspired by Storyblok (https://www.storyblok.com/docs/api/content-delivery/v2/filter-queries)

        Implementation note:
        - The availability and behaviour of this query functionality are entirely determined by the organisation hosting
          the API implementation. It is not mandatory for implementers to support this functionality, and it cannot be enforced 
          upon organisations that provide or consume OOAPI endpoints.
        - It is up to each implementer to decide whether to support this feature. It is **not** a requirement of the OOAPI 
          standard itself.
        - Consumers or working groups that wish to apply specific filtering mechanisms are encouraged to do so using 
          this approach for the sake of consistency across implementations.
      enum:
        - empty
        - not_empty
        - empty_array
        - not_empty_array
        - 'true'
        - 'false'
        - 'null'
        - not_null
      example: not_empty
    academicSessionType:
      type: string
      description: |
        The type of this academic session. This is an *extensible enumeration*.

        - academic_year: Academic year
        - semester: Semester, typically comprising two terms per academic year
        - trimester: Trimester, typically comprising three terms per academic year
        - quarter: Quarter, typically comprising four terms per academic year
        - testing_period: A period during which tests take place
        - period: Any other period within an academic year

        Implementations may add further values beyond those listed above, provided they do not overlap in definition with existing values.
      x-ooapi-extensible-enum:
        - academic_year
        - semester
        - trimester
        - quarter
        - testing_period
        - period
      example: semester
    Pagination:
      type: object
      required:
        - pageSize
        - pageNumber
        - hasPreviousPage
        - hasNextPage
      properties:
        pageSize:
          type: integer
          format: int32
          description: The number of items per page
          example: 10
        pageNumber:
          type: integer
          format: int32
          description: The current page number
          example: 1
          minimum: 1
        hasPreviousPage:
          type: boolean
          description: Whether there is a previous page
          example: false
        hasNextPage:
          type: boolean
          description: Whether there is a previous page
          example: true
        totalPages:
          type:
            - integer
            - 'null'
          format: int32
          description: Total number of pages
          example: 8
    codeType:
      type: string
      description: |
        The type of code or identifier.

        The predefined values are:

        | Code                      | Description                                                       |
        |---------------------------|-------------------------------------------------------------------|
        | `account_id`              | Identifier for an account.                                        |
        | `bag_id`                  | Identifier for a building in the Dutch Building and Address       |
        |                           | Registry (BAG).                                                   |
        | `building_id`             | Identifier for a building.                                        |
        | `component_code`          | Identifier for a component (part of a course).                    |
        | `eckid`                   | Identifier assigned within the Dutch *Educatieve ContentKeten iD* |
        |                           | framework. It enables persistent identification and exchange of   |
        |                           | digital learning resources within the Dutch educational sector for|
        |                           | EQF levels 1, 2, 3 and 4. Comparable international approaches     |
        |                           | include LRMI, DOI and Handle                                      |
        |                           | identifiers for learning resources.                               |
        | `email_address`           | An email address.                                                 |
        | `esi`                     | European Student Identifier.                                      |
        | `group_code`              | Identifier for a group of people.                                 |
        | `group_type_code`         | Identifier for the type of group.                                 |
        | `identifier`              | Generic identifier.                                               |
        | `institution_code`        | Registration number of an educational institution. In the         |
        |                           | Netherlands, the former BRIN code has been replaced by the        |
        |                           | institution code, issued by the Ministry of Education, Culture    |
        |                           | and Science (OCW).                                                |
        | `isbn`                    | International Standard Book Number (for books).                   |
        | `issn`                    | International Standard Serial Number (for periodicals).           |
        | `kvk_organisation_id`     | Identifier for a KvK (Dutch Chamber of Commerce) registered       |
        |                           | organisation.                                                     |
        | `kvk_establishment_id`    | Identifier for a specific establishment of a KvK                  |
        |                           | (Dutch Chamber of Commerce) registered organisation.              |
        | `leerbedrijf_id`          | Dutch registration/accreditation id for organisations offering    |
        |                           | internships for vocational education students.                    |
        | `national_identity_number`| Government-assigned personal identifier (e.g. NI number in the UK,|
        |                           | or *personnummer* in Sweden).                                     |
        | `offering_code`           | Identifier for a specific offering (programme, course or          |
        |                           | component).                                                       |
        | `organisation_id`         | Identifier for an organisation.                                   |
        | `orcid`                   | Open Researcher and Contributor ID.                               |
        | `product_id`              | Identifier for a product.                                         |
        | `programme_code`          | Identifier of a programme (a recognised collection of courses).   |
        |                           | In the Netherlands, the former CREBO and CROHO codes have been    |
        |                           | replaced by the programme code as registered in RIO, under the    |
        |                           | authority of OCW.                                                 |
        | `room_code`               | Identifier for a room.                                            |
        | `schac_home`              | Home organisation represented by its domain name.                 |
        | `student_number`          | Identifier for a student.                                         |
        | `studielink_number`       | Identifier assigned to a student by Studielink (Dutch central     |
        |                           | enrolment system).                                                |
        | `system_id`               | Identifier used within a specific system.                         |
        | `username`                | User login name.                                                  |
        | `uuid`                    | Universally unique identifier.                                    |

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - account_id
        - bag_id
        - building_id
        - component_code
        - eckid
        - email_address
        - esi
        - group_code
        - group_type_code
        - identifier
        - institution_code
        - isbn
        - issn
        - kvk_organisation_id
        - kvk_establishment_id
        - leerbedrijf_id
        - offering_code
        - organisation_id
        - orcid
        - product_id
        - programme_code
        - room_code
        - schac_home
        - student_number
        - studielink_number
        - system_id
        - username
        - uuid
        - national_identity_number
      example: identifier
    IdentifierEntry:
      type: object
      properties:
        codeType:
          $ref: '#/components/schemas/codeType'
        code:
          description: Human readable value for the code/identifier
          type: string
          example: 1234qwe12
      required:
        - codeType
        - code
      additionalProperties: false
      example:
        codeType: identifier
        code: 1234qwe12
    Language:
      description: |
        The language used in the described entity. A string formatted according to RFC 4647 https://www.rfc-editor.org/rfc/rfc4647.html
        RFC 4647 supports language specifications from very general to very specific. 
        This breaks down as:
        - ([a-z]{2,3}) - Primary language subtag (2-3 letters) ISO 639-1, ISO 639-2, or ISO 639-3 https://www.iso.org/iso-639-language-code
        - (-([A-Z]{2}|[0-9]{3}))? - Optional region/country (2 uppercase letters or 3 digits) ISO 3166-1 or UN M.49 https://www.iso.org/iso-3166-country-codes.html
        - (-([a-z]{4}))? - Optional script subtag (4 lowercase letters)
        - (-([a-z]{2}|[0-9]{3}))* - Optional variant subtags
        - (-[a-z0-9]{2,8})* - Optional extension subtags
        - (-x(-[a-z0-9]{1,8})+)? - Optional private use extensions

        When using this schema, the most common format is a two-letter language code as specified by ISO 639-1, optionally followed by a dash and a two-letter country code as specified by ISO 3166-1 (e.g. "en" or "en-GB").
        More specific language tags are also allowed, such as "zh-Hant-TW" for Traditional Chinese as used in Taiwan.
        For sign language based on a certain language two methods are commonly used: either using the subtag "sgn" (e.g. "nl-sgn-NL" for Dutch Sign Language) or using the subtag "s" (e.g. "nl-s-NL" for Dutch Sign Language). Both methods are allowed.
      type: string
      minLength: 2
      pattern: ^([a-z]{2,3})(-([A-Z]{2}|[0-9]{3}))?(-([a-z]{4}))?(-([a-z]{2}|[0-9]{3}))*(-[a-z0-9]{2,8})*(-x(-[a-z0-9]{1,8})+)?$
      example: en-GB
    LanguageTypedString:
      type: object
      description: A String with an associated language code. IF this object is used both fields are mandatory.
      required:
        - language
        - value
      properties:
        language:
          $ref: '#/components/schemas/Language'
        value:
          description: String to describe the entity.
          type: string
          example: programme that is a place holder for all courses that are made available for student mobility
      example:
        language: en-GB
        value: programme that is a place holder for all courses that are made available for student mobility
    Identifier:
      type: string
      description: An identifier of another resource.
      format: uuid
      example: 123e4567-e89b-12d3-a456-426614174000
    offeringState:
      type: string
      description: |
        The state of this offering:

        - concept: The offering is still in development and not yet available for students
        - cancelled: The offering has been cancelled and is no longer available
        - active: The offering is currently available for students to enrol in and participate
        - inactive: The offering is not currently available for students, but may be available in the future

        This is an extensible enumeration. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - concept
        - cancelled
        - active
        - inactive
      example: active
    CourseOfferingId:
      type: object
      required:
        - courseOfferingId
      properties:
        courseOfferingId:
          type: string
          description: The unique ID of the course offering, this should be unique across all programme, course, learning, and test component offerings.
          format: uuid
          example: 123e4567-e89b-12d3-a456-134564174000
    rosteringState:
      type: string
      description: |
        Precision indicator with values for rostering purposes:
          
        - definitive: Confirmed final timeslot.
        - preliminary: Broadest possible time range, will be further refined.
        - tentative: Scheduled but subject to change.

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - definitive
        - preliminary
        - tentative
      example: definitive
    modeOfDelivery:
      type: string
      description: |
        The mode of delivery of the component, based on the EU vocabulary:  
        https://op.europa.eu/en/web/eu-vocabularies/dataset/-/resource?uri=http://publications.europa.eu/resource/dataset/learning-assessment

        | Code                 | Description                                               |
        |----------------------|-----------------------------------------------------------|
        | `blended`            | Structured combination of online and in-person learning   |
        | `coil`               | Collaborative Online International Learning; joint, cross-|
        |                      | institutional, online delivery (virtual exchange /        |
        |                      | co-taught across institutions)                            |
        | `hybrid`             | Delivery using different modes in a flexible and          |
        |                      | interchangeable way                                       |
        | `joint_delivery`     | Programme delivered collaboratively by two or more        |
        |                      | institutions (national or international), with shared     |
        |                      | responsibility for curriculum and teaching                |
        | `online`             | Real-time learning delivered entirely via the internet    |
        | `presential`         | Learning that takes place in a physical classroom setting |
        | `project_based`      | Learning or assessment conducted as part of a project team|
        | `research_lab_based` | Learning that occurs within a research environment        |
        | `work_based`         | Learning through practical work or workplace experience   |

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - blended
        - coil
        - hybrid
        - joint_delivery
        - online
        - presential
        - project_based
        - research_lab_based
        - work_based
      example: blended
    resultValueType:
      type: string
      description: |
        The result value type for this offering.

        - pass_or_fail: A simple pass or fail result.
        - insufficient_satisfactory_good: A result with three levels (insufficient, satisfactory and good).
        - us_letter: A result in the US letter grading system (A, B, C, D, F).
        - uk_letter: A result in the UK letter grading system (A, B, C, D, E, U).
        - de_grade: A result in the German grading system (1, 2, 3, 4, 5, 6).
        - grade_0_100: A result in the 0–100 grading system.
        - grade_0_10: A result in the 0–10 grading system (no decimals allowed).
        - grade_0_10_one_decimal: A result in the 0–10 grading system (with one decimal place).
        - reference_level_europass: A result in the Europass reference level grading system (A1, A2, B1, B2, C1, C2).
        - other: Any other grading system not specified above.

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - pass_or_fail
        - insufficient_satisfactory_good
        - us_letter
        - uk_letter
        - de_grade
        - grade_0_100
        - grade_0_10
        - grade_0_10_one_decimal
        - reference_level_europass
        - other
      example: grade_0_10
    EnrolmentPeriods:
      type: object
      description: |
        An enrolment period describes the moment at which an offering is available for enrolment.
        The enrolment period is supplemented with additional information regarding the intended users, the time for the enrolment as well as a URL that contains the enrolment logic.
      required:
        - startDateTime
      properties:
        startDateTime:
          type: string
          description: The moment from which the enrolment should be available
          format: date-time
          example: '2020-09-28T08:30:00+01:00'
        endDateTime:
          type:
            - string
            - 'null'
          description: The moment until which the enrolment should be available (when the enrolment for this target group stops), RFC3339 (date-time)
          format: date-time
          example: '2020-09-30T20:00:00+01:00'
        targetGroups:
          type:
            - array
            - 'null'
          description: The people for whom this enrolment is available.
          items:
            type: string
            description: the specific target group
        enrolmentType:
          type:
            - string
            - 'null'
          description: |
            The way the enrolment process should be handled for this period and target group. 
            Likely values are:
              url - a url where the user should be directed to for finishing the enrolment
              broker - using a system that is specialized to handle enrolment
          example: url
        enrolmentUrl:
          type:
            - string
            - 'null'
          description: The URL where a person of this target group can enrol him or herself
          example: https://university.example.org/
        queueEnabled:
          type:
            - boolean
            - 'null'
          description: |
            a boolean value (true or false) indicating whether enrolment is queued.
          example: false
        queuedNumberStudents:
          type:
            - number
            - 'null'
          description: The number of students that have a queued enrolment state for this offering.
          format: int32
          minimum: 0
          example: 200
        maxQueuedNumberStudents:
          type:
            - number
            - 'null'
          description: The maximum number of students allowed in the queue for this offering.
          format: int32
          minimum: 0
          example: 200
        comment:
          type:
            - string
            - 'null'
          description: Additional information regarding this enrolment period that can be shared with the persons in the target groups.
          example: Additional information...
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    supplementaryRole:
      type: string
      description: |
        The fundamental semantic purpose of the supplementary content. The selected
        `role` describes the intent or function of the item (for example, badge,
        teaser or promotional highlight).

        The `role` MUST NOT duplicate or encode the technical media form defined by
        `type`. The `type` specifies the underlying media form (such as text, image,
        video or http), whereas the `role` clarifies how that media is intended to be
        interpreted or used.

        | Code           | Description                                         |
        |----------------|-----------------------------------------------------|
        | `announcement` | General-purpose announcement or notice              |
        | `badge`        | A visual label or achievement marker                |
        | `marketing`    | Promotional or marketing-related content            |
        | `promo`        | A short promotional highlight or teaser             |

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - announcement
        - badge
        - marketing
        - promo
      example: badge
    supplementaryType:
      type: string
      description: |
        The fundamental media form of the supplementary content. The selected `type`
        determines how the associated `value` MUST be interpreted. It defines the
        technical representation of the content, independent of its semantic role.

        The `type` specifies the underlying media form, such as text_plain,
        text_md, text_http, image, video or uri.

        The `role` defines the semantic intent of the item and MUST NOT duplicate the
        technical media form defined by `type`.

        | Code        | Description                                                              |
        |-------------|--------------------------------------------------------------------------|
        | `image`     | Visual media referenced via a URI (for example photographs or artwork)   |
        | `text_http` | HTTP-encoded textual content                                             |
        | `text_md`   | Markdown-formatted text content.                                         |
        | `text_plain`| Plain text content.                                                      |
        | `uri`       | A URI linking to an external resource                                    |
        | `video`     | Video media referenced via a URI (for example recordings or trailers)    |

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - image
        - text_http
        - text_md
        - text_plain
        - uri
        - video
      example: text_plain
    SupplementaryInformation:
      type: array
      description: Optional supplementary information associated with this resource.
      items:
        type: object
        description: |
          A supplementary content item consists of a technical media form (`type`),
          a semantic purpose (`role`), and an array of `value` entries. Together these
          fields define both how the content MUST be interpreted (`type`) and why it
          is provided (`role`).

          The `type` specifies the underlying media form (text, image, video or http)
          and determines how each `value` item MUST be handled. The `role` describes
          the intent or purpose of the supplementary item (for example announcement,
          badge, marketing or promotional teaser) and MUST NOT duplicate or encode
          the media form defined by `type`.

          The separation between `type` and `role` ensures that the same media form
          can serve multiple purposes, and that the semantic meaning remains
          independent from the technical representation of the content. The `value`
          array contains one or more language-typed strings, allowing the same content
          item to be expressed in multiple languages or alternative textual variants.
        properties:
          role:
            $ref: '#/components/schemas/supplementaryRole'
          type:
            $ref: '#/components/schemas/supplementaryType'
          value:
            type: array
            minItems: 1
            items:
              $ref: '#/components/schemas/LanguageTypedString'
        required:
          - role
          - type
          - value
    OfferingProperties:
      type: object
      required:
        - primaryCode
        - name
      properties:
        primaryCode:
          description: The primary human readable identifier for this offering. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: offeringCode
            code: INFOMQNM-20FS
        groupIds:
          description: |
            The offering identifiers (0..N) associated with this group.
          oneOf:
            - type: array
              items:
                $ref: '#/components/schemas/Identifier'
            - type: 'null'
        academicSessionId:
          description: |
            The identifier of the academicSession during which this courseOffering takes place.
            When the client does not request expansion of `academicSession`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        academicSession:
          description: |
            The expanded academicSession object during which this courseOffering takes place.
            When the client requests expansion of `academicSession`, the full expanded academicSession object MUST be returned here instead of only the identifier.
            If no academicSession is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/AcademicSession'
        name:
          type: array
          description: The name of this offering
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Final written test for INFOMQNM for fall semester 2020
        state:
          description: The state of this offering, e.g. active, inactive, archived
          oneOf:
            - $ref: '#/components/schemas/offeringState'
            - type: 'null'
        rosteringState:
          description: The rostering state of this offering indicating the state in relation to planning, e.g. active, inactive, archived
          oneOf:
            - $ref: '#/components/schemas/rosteringState'
            - type: 'null'
        abbreviation:
          type:
            - string
            - 'null'
          description: The abbreviation or internal code used to identify this offering
          maxLength: 256
          example: Test-INFOMQNM-20FS
        description:
          type:
            - array
            - 'null'
          description: The description of this offering.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: |
                'Prove in writing knowledge of research methods, including:
                Acquire knowledge of HCI research paradigms
                Able to design suitable research studies (e.g., choose between within and between subject designs)
                Define/apply/design metrics and scales
                Define/produce materials (e.g., stimuli and questionnaires)
                Define protocols for research studies
                Understands and take in account concepts of reliability and validity
                Analyse and improve methods and analysis of published scientific articles
                Able to deliver scientific reports
                Prove in writing knowledge of ­­­statistics, including:
                Handle hypothesis testing with complex designs (e.g., including , dependent, independent, and co variates)
                Data preparation (e.g., coding and feature selection)
                Reason towards adequate techniques to ensure valid outcomes (e.g., be aware of type I, type II errors)
                Select an appropriate sampling method (e.g., stratified)
                Perform parametric tests (e.g., repeated measures (M)ANOVA)
                Perform non-parametric tests (e.g., Chi-square, Mann-Whitney, and Kruskal-Wallis)'
        teachingLanguages:
          type:
            - array
            - 'null'
          description: The languages in which this course is given, should at least a two-letter language code as specified by RFC 4647. A student should be reasonably proficient in each language to be able to follow the offering.
          minItems: 1
          items:
            $ref: '#/components/schemas/Language'
        modesOfDelivery:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/modeOfDelivery'
        maxNumberStudents:
          type:
            - number
            - 'null'
          description: The maximum number of students allowed to enrol for this offering
          format: int32
          minimum: 0
          example: 200
        enrolledNumberStudents:
          type:
            - number
            - 'null'
          description: The number of students who have already enrolled for this offering
          format: int32
          minimum: 0
          example: 150
        pendingNumberStudents:
          type:
            - number
            - 'null'
          description: The number of students who have a pending enrolment request for this offering
          format: int32
          minimum: 0
          example: 50
        minNumberStudents:
          type:
            - number
            - 'null'
          description: The minimum number of students needed for this offering to proceed
          format: int32
          minimum: 0
          example: 15
        resultExpected:
          type:
            - boolean
            - 'null'
          description: |
            resultExpected, previously known as isLineItem is used so the specific instance of the object is 
            identified as being an element that CAN contain “grade” information.
            Offerings need not always result in a grade or another type of result. 
            If there is a result expected from a programmeOffering/courseOffering/componentOffering the 
            is resultExpected field should be set to true
          example: true
        resultValueType:
          oneOf:
            - $ref: '#/components/schemas/resultValueType'
            - type: 'null'
        link:
          type:
            - string
            - 'null'
          description: URL of this offering's webpage.
          format: uri
          maxLength: 2048
          example: https://osiris.uu.nl/osiris_student_uuprd/OnderwijsCatalogusZoekCursus.do#submitForm?cursuscode=INFOMQNM
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
        enrolmentPeriods:
          type:
            - array
            - 'null'
          description: An array of periods that a person can enrol into this offering. The period is defined by target group and dateTime
          items:
            $ref: '#/components/schemas/EnrolmentPeriods'
        supplementaryInformation:
          $ref: '#/components/schemas/SupplementaryInformation'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    addressType:
      type: string
      description: |
        The type of address, indicating its intended use:
          
        - postal: Used for receiving post
        - visit: Used for physical visits
        - deliveries: Used for deliveries
        - invoicing: Used for invoicing purposes
        - teaching: The location where educational activities take place

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - postal
        - visit
        - deliveries
        - invoicing
        - teaching
      example: postal
    Country:
      type: object
      description: |
        An object indicating a country based on at least one iso-3166 code. In situations where more than one ISO-3166 code is provided, the codes must refer to the same country.
      properties:
        iso3166-1-alpha2:
          type:
            - string
            - 'null'
          minLength: 2
          maxLength: 2
          description: A country code based on https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
          example: NL
        iso3166-1-alpha3:
          type:
            - string
            - 'null'
          minLength: 3
          maxLength: 3
          description: A country code based on https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3
          example: NLD
        iso3166-2:
          type:
            - string
            - 'null'
          minLength: 5
          maxLength: 6
          description: A country subdivision code based on https://en.wikipedia.org/wiki/ISO_3166-2
          example: BQ-BO
        iso3166-3:
          type:
            - string
            - 'null'
          minLength: 4
          maxLength: 4
          description: |
            A code for a country that no longer exists is listed on ISO 3166-3 (https://en.wikipedia.org/wiki/ISO_3166-3).
            Implementations should refrain from using the original ISO 3166-1 code for such a country since country codes
            can be reassigned to new countries once the original country code is officially declared obsolete.
          example: ANHH
    Address:
      type: object
      description: The full street address
      required:
        - addressType
      properties:
        addressType:
          $ref: '#/components/schemas/addressType'
        street:
          type:
            - string
            - 'null'
          description: The street name
          example: Moreelsepark
        streetNumber:
          type:
            - string
            - 'null'
          description: The street number
          example: '48'
        additional:
          type:
            - array
            - 'null'
          description: Further details like building name, suite, apartment number, etc.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: On the other side of the road
        postCode:
          type:
            - string
            - 'null'
          description: Code to help sort and deliver mail also known as Postal code and ZIP code
          example: 3511 EP
        city:
          type:
            - string
            - 'null'
          description: name of the city / locality
          example: Utrecht
        countryCode:
          oneOf:
            - $ref: '#/components/schemas/Country'
            - type: 'null'
        geolocation:
          type:
            - object
            - 'null'
          description: Geolocation of the entrance of this address (WGS84 coordinate reference system)
          required:
            - latitude
            - longitude
          properties:
            latitude:
              type: number
              format: double
              example: 52.089123
            longitude:
              type: number
              format: double
              example: 5.113337
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    costType:
      type: string
      description: |
        The type of cost. This is an *extensible enumeration*.

        The following values are defined in the specification:
          
          - stap_eligible: costs for which a student may receive STAP funding
          - total_costs: the total amount a student is required to pay to participate in this offering

        Implementations may add additional values beyond those listed above, provided they do not overlap in meaning with existing values.
      x-ooapi-extensible-enum:
        - stap_eligible
        - total_costs
      example: total_costs
    Cost:
      type: object
      required:
        - costType
      properties:
        costType:
          $ref: '#/components/schemas/costType'
        amount:
          type:
            - string
            - 'null'
          pattern: ^\d+(?:\.\d+)?$
          description: The total amount of the cost as a string. Use a '.' (dot) as an optional separator. The numbers before the separator signify the major units of the currency, after the dot the minor units. Only a single separator is allowed. Do not use a comma.
          example: '340.84'
        vatAmount:
          type:
            - string
            - 'null'
          pattern: ^\d+(?:\.\d+)?$
          description: The part of the cost that is VAT, as a string. Use a '.' (dot) as an optional separator. The numbers before the separator signify the major units of the currency, after the dot the minor units. Only a single separator is allowed. Do not use a comma.
          example: '40'
        amountWithoutVat:
          type:
            - string
            - 'null'
          pattern: ^\d+(?:\.\d+)?$
          description: The part of the cost that is non-VAT. as a string. Use a '.' (dot) as an optional separator. The numbers before the separator signify the major units of the currency, after the dot the minor units. Only a single separator is allowed. Do not use a comma.
          example: '300.84'
        currency:
          type:
            - string
            - 'null'
          description: The currency this cost is in. Should correspond to one of the currency codes from ISO 4217.
          example: EUR
        displayAmount:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          description: An array of optional pre-formatted strings in different locales. Clients can choose to use this string instead of rendering their own based on the current locale of the user.
          example:
            - language: nl-NL
              value: €380,84
            - language: en-US
              value: $401.17
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
      additionalProperties: false
    CourseId:
      type: object
      description: An object describing the metadata of a course
      required:
        - courseId
      properties:
        courseId:
          type: string
          description: Unique id of this course
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
    studyloadUnit:
      type: string
      description: |
        The unit in which the study load is specified:

        - contact_time: Amount of time spent in scheduled classroom or contact hours.
        - ects: European Credit Transfer and Accumulation System (ECTS credits), typically 1 ECTS = 28 study hours.
        - sbu: Student workload hours, representing the total estimated effort.
        - sp: Study points used in some national systems (e.g. studiepunt in Flanders or the Netherlands).
        - hour: Plain number of hours, regardless of context (e.g. used for informal or modular learning units).

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - contact_time
        - ects
        - sbu
        - sp
        - hour
      example: ects
    StudyLoadDescriptor:
      type: object
      description: The amount of effort to complete this education in the specified unit.
      required:
        - studyLoadUnit
        - value
      properties:
        studyLoadUnit:
          $ref: '#/components/schemas/studyloadUnit'
        value:
          description: The amount of load depicted in numbers
          type: number
          example: 3
      example:
        studyLoadUnit: ects
        value: 3
    learningOutcomeLevel:
      type: string
      description: |
        The level of the learning outcome. This field supports multiple frameworks for
        describing cognitive complexity. Two common frameworks are provided below: **Bloom’s**
        and **SOLO**. These are intended as examples — additional levels or entirely
        different frameworks MAY be added as needed.

        **Bloom’s taxonomy** ([https://en.wikipedia.org/wiki/Bloom's_taxonomy](https://en.wikipedia.org/wiki/Bloom's_taxonomy)):

        | Level   | Label      | Description                                                         |
        |---------|------------|---------------------------------------------------------------------|
        | bloom_1 | Remember   | Recall facts and basic concepts (define, list, state).              |
        | bloom_2 | Understand | Explain ideas or concepts (describe, discuss, explain).             |
        | bloom_3 | Apply      | Use knowledge in new situations (implement, solve, use).            |
        | bloom_4 | Analyse    | Draw connections among ideas (differentiate, compare, examine).     |
        | bloom_5 | Evaluate   | Justify a decision or course of action (critique, assess, argue).   |
        | bloom_6 | Create     | Produce new or original work (design, construct, develop).          |

        **SOLO taxonomy** ([https://en.wikipedia.org/wiki/Structure_of_observed_learning_outcome](https://en.wikipedia.org/wiki/Structure_of_observed_learning_outcome)):

        | Level   | Label             | Description                                                     |
        |---------|-------------------|-----------------------------------------------------------------|
        | solo_0  | Prestructural     | No understanding; the student misses the point.                 |
        | solo_1  | Unistructural     | Identifies or carries out simple procedures; limited to one     |
        |         |                   | relevant aspect.                                                |
        | solo_2  | Multistructural   | Addresses several relevant aspects, but sees them as unrelated; |
        |         |                   | knowledge is additive.                                          |
        | solo_3  | Relational        | Integrates aspects into a coherent whole, showing deeper        |
        |         |                   | understanding of relationships.                                 |
        | solo_4  | Extended abstract | Generalises and applies learning to new domains, showing        |
        |         |                   | theoretical and abstract thinking.                              |

        This is an *extensible enumeration*. Implementers MAY introduce other recognised
        taxonomies, institutional or national frameworks.  
      x-ooapi-extensible-enum:
        - bloom_1
        - bloom_2
        - bloom_3
        - bloom_4
        - bloom_5
        - bloom_6
        - solo_0
        - solo_1
        - solo_2
        - solo_3
        - solo_4
      example: bloom_1
    level:
      type: string
      description: |
        The level of this course (ECTS year of study if applicable):

        - pre_vocational: Pre-vocational education, preparatory stage prior to vocational training, typically before secondary vocational education (Dutch: mbo) level
        - secondary_vocational_education: Secondary vocational education (Dutch: mbo)
        - secondary_vocational_education_1: Secondary vocational education level 1, corresponds to levelOfQualification 1 (Dutch: mbo 1)
        - secondary_vocational_education_2: Secondary vocational education level 2, corresponds to levelOfQualification 2 (Dutch: mbo 2)
        - secondary_vocational_education_3: Secondary vocational education level 3, corresponds to levelOfQualification 3 (Dutch: mbo 3)
        - secondary_vocational_education_4: Secondary vocational education level 4, corresponds to levelOfQualification 4 (Dutch: mbo 4)
        - associate_degree: Associate degree, corresponds to levelOfQualification 5
        - bachelor: Bachelor degree, corresponds to levelOfQualification 6
        - master: Master degree, corresponds to levelOfQualification 7
        - doctoral: Doctoral level, corresponds to levelOfQualification 8
        - post_doctoral: Post-doctoral level, advanced academic or professional qualification beyond the doctoral level
        - undefined: The level is not specified
        - undivided: Integrated programme not divided into bachelor and master phases
        - nt2_1: Dutch as a second language, Programme I, intended for vocational training (CEFR level A2–B1)
        - nt2_2: Dutch as a second language, Programme II, intended for higher education or professional purposes (CEFR level B2)

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - pre_vocational
        - secondary_vocational_education
        - secondary_vocational_education_1
        - secondary_vocational_education_2
        - secondary_vocational_education_3
        - secondary_vocational_education_4
        - associate_degree
        - bachelor
        - master
        - doctoral
        - post_doctoral
        - undefined
        - undivided
        - nt2_1
        - nt2_2
      example: master
    ProgrammeId:
      type: object
      description: A collection of courses that lead to a certifiable learning outcome
      required:
        - programmeId
      properties:
        programmeId:
          type: string
          description: Unique id for this programme
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
    programmeType:
      type: string
      description: |
        The type of this programme:

        - programme: A full formal programme of study leading to a qualification or degree
        - minor: A smaller, complementary programme that broadens or deepens the main field of study
        - honours: An honours programme, typically with additional academic requirements or distinction
        - specialisation: A focused area of study within a broader programme or degree
        - track: A structured learning path within a programme, often thematically or methodologically defined
        - specification: A further defined variant or subset of a track or specialisation

        This is an extensible enumeration. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - programme
        - minor
        - honours
        - specialisation
        - track
        - specification
      example: programme
    qualificationAwarded:
      type: string
      description: |
        Type of qualification that can be obtained upon completing the programme:
        - diploma
        - vocational_diploma
        - certificate
        - associate_degree: Associate degree — short-cycle higher education qualification (EQF level 5)
        - bachelor: Bachelor — undergraduate degree (EQF level 6)
        - master: Master — postgraduate degree (EQF level 7)
        - doctoral: Doctoral degree — research-based doctoral degree (EQF level 8)
        - none: No formal qualification is awarded for this programme

        In case of a degree (for example bachelor or master), the type of degree can be specified using `qualificationDesignations`.
      x-ooapi-extensible-enum:
        - diploma
        - vocational_diploma
        - certificate
        - associate_degree
        - bachelor
        - master
        - doctoral
        - none
      example: none
    modeOfStudy:
      type: string
      description: |
        Indicates the mode of study: full-time, part-time, dual or self-paced.

        - full_time: Standard daytime study schedule
        - part_time: Study scheduled outside regular working hours, such as evenings and weekends
        - dual_training: Combination of workplace learning and academic study
        - self_paced: Student sets their own pace and timing for study

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - full_time
        - part_time
        - dual_training
        - self_paced
      example: full_time
    levelOfQualification:
      type: string
      description: |
        Level of qualification according to the European Qualifications Framework (EQF).  
        See:  
        - https://europass.europa.eu/en/description-eight-eqf-levels  
        - https://europass.europa.eu/en/europass-digital-tools/european-qualifications-framework  
        - https://nlqf.nl/
        - https://database.nlqf.nl/assets/pdf/schema-en-print.pdf

        This list is extended with:
        - eqf_0: Informal or pre-qualification learning, below EQF level 1, e.g. basic literacy or life skills
        - eqf_1: Basic general knowledge and skills to carry out simple tasks
        - eqf_2: Basic factual knowledge and practical skills in a field of work or study
        - eqf_3: Knowledge of facts, principles and processes, with basic problem-solving skills
        - eqf_4: Factual and theoretical knowledge in broad contexts within a field of work or study
        - nlqf_4plus: Dutch pre-university education (VWO), considered above EQF level 4 but not formally mapped to EQF level 5
        - eqf_5: Comprehensive, specialised knowledge and practical skills, typically short-cycle higher education (e.g. associate degree)
        - eqf_6: Advanced knowledge and skills for complex problem-solving, typically bachelor level
        - eqf_7: Highly specialised knowledge and critical awareness, typically master level
        - eqf_8: Knowledge at the most advanced frontier of a field, typically doctoral level

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - eqf_0
        - eqf_1
        - eqf_2
        - eqf_3
        - eqf_4
        - nlqf_4plus
        - eqf_5
        - eqf_6
        - eqf_7
        - eqf_8
      example: eqf_6
    formalDocument:
      type: string
      description: |
        The type of formal document obtained upon completion of an educational programme:

        | Code                        | Description                                    |
        |-----------------------------|------------------------------------------------|
        | `certificate`               | A formal recognition of participation or       |
        |                             | achievement                                    |
        | `diploma`                   | An official qualification awarded upon         |
        |                             | graduation                                     |
        | `micro_credential_certificate` | Formal certification specifically           |
        |                             | documenting the award of a micro-credential    |
        | `school_advice`             | Educational recommendation or guidance issued  |
        |                             | by the school                                  |
        | `testimonial`               | A written statement confirming attendance or   |
        |                             | performance                                    |
        | `no_official_document`      | No official document is issued                 |

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - certificate
        - diploma
        - micro_credential_certificate
        - school_advice
        - testimonial
        - no_official_document
      example: diploma
    PersonId:
      type: object
      properties:
        personId:
          type: string
          description: Unique id of this person
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
      required:
        - personId
    Nationality:
      type: object
      description: |
        An object indicating nationality based on at least one iso-3166 code. In situations where more than one iso-3166 code is provided the codes have address the same country.
      properties:
        iso3166-1-alpha2:
          type:
            - string
            - 'null'
          minLength: 2
          maxLength: 2
          description: A country code based on https://en.wikipedia.org/wiki/ISO_3166-1_alpha-2
          example: NL
        iso3166-1-alpha3:
          type:
            - string
            - 'null'
          minLength: 3
          maxLength: 3
          description: A country code based on https://en.wikipedia.org/wiki/ISO_3166-1_alpha-3
          example: NLD
        iso3166-3:
          type:
            - string
            - 'null'
          minLength: 4
          maxLength: 4
          description: |
            A nationality code for a country that no longer exists on https://en.wikipedia.org/wiki/ISO_3166-3 It is not advised to use the original iso3166-1 for such a country since country codes can get reassigned to new countries ones the original country code is officially obsolete. It is possible that a person has a nationality of a country that does not exist any more (after a country got split up like CZ and YU)\ and never applied for nationality of one of the new countries.
          example: ANHH
    personAffiliation:
      type: string
      description: |
        The affiliations of this person — the roles or relationships a person has with the organisation providing this endpoint:

        - student: Enrolled learner or participant in educational offerings
        - employee: Staff member employed by the organisation (e.g. teacher, administrator)
        - guest: External person temporarily affiliated, without formal student or employee status

        This is an extensible enumeration. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - student
        - employee
        - guest
      example: student
    gender:
      type: string
      description: |
        The gender of this person, based on international standards for education and data interoperability.

        The values follow practices from agencies such as:
        - European Commission (EULF, INSPIRE, GeoDCAT-AP)
        - Edustandaard, EUNIS

        - m: male
        - f: female
        - x: non-binary or gender-diverse, officially registered
        - o: other gender identity, not officially classified as m/f/x
        - u: unknown or not registered
        - n: not applicable, e.g. for non-person entities or gender-irrelevant use cases
      x-ooapi-extensible-enum:
        - m
        - f
        - x
        - o
        - u
        - 'n'
      example: f
    ICERelationType:
      type: string
      description: |
        The type of relationship between the person and their In Case of Emergency (ICE) contact:

        - partner: Spouse or life partner
        - parent: Biological, adoptive, or legal parent
        - other: Any other type of relationship (e.g. sibling, friend, neighbour)

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - partner
        - parent
        - other
      example: partner
    PersonProperties:
      type: object
      description: A person that has a relationship with this institution
      anyOf:
        - required:
            - surname
            - primaryCode
            - activeEnrolment
        - title: With required given name
          required:
            - givenName
            - primaryCode
            - activeEnrolment
        - title: With required preferred name
          required:
            - preferredName
            - primaryCode
            - activeEnrolment
      properties:
        primaryCode:
          description: The primary human readable identifier for the person. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: studentNumber
            code: 0
        givenName:
          type:
            - string
            - 'null'
          description: The first name of this person
          maxLength: 256
          example: Martina
        alternateName:
          type:
            - string
            - 'null'
          description: The Name a person chooses to use. this is part of a Self Sovereign name e.g. in the eduId process comparable to schema.org alternateName
          maxLength: 256
          example: Marieke
        preferredName:
          type:
            - string
            - 'null'
          description: The name how the person would like to be called. Usually first name of this person. In line with ISO/IEC 24760 – Identity Management Vocabulary
          maxLength: 256
          example: Maartje
        surnamePrefix:
          type:
            - string
            - 'null'
          description: The prefix of the family name of this person
          example: van
        surname:
          type: string
          description: The family name of this person
          maxLength: 256
          example: Damme
        displayName:
          type:
            - string
            - 'null'
          description: The name of this person which will be displayed
          maxLength: 256
          example: Maartje van Damme
        initials:
          type:
            - string
            - 'null'
          description: The initials of this person
          example: MCW
        idCheckName:
          type:
            - string
            - 'null'
          description: |
            The name of the person as printed on official identification documents
            (driving licence, passport or identity card). This MUST be formatted as
            "surname prefix surname, given names" (separating surnamePrefix and surname
            with a single space, and surname and given names with a comma and space).

            If the surname or given names are not available or are secret, the values
            "secret" and "not_available" are recommended. The surname prefix may be
            omitted. E.g. "van der Graaf, Jacobus Adrianus". 

            Optionally, the value of
            the student number can be added to this field by appending it at the end,
            separated by a comma. E.g. "van der Graaf, Jacobus Adrianus, s12345678"
          example: van der Graaf, Jacobus Adrianus, s12345678
        activeEnrolment:
          type: boolean
          description: Whether this person has an active enrolment.
          example: false
        dateOfBirth:
          type:
            - string
            - 'null'
          description: |
            The date of birth of this person, using the `full-date` format as defined in 
            RFC 3339 (section 5.6).
          format: date
          example: '2003-09-30'
        cityOfBirth:
          type:
            - string
            - 'null'
          description: The city of birth of this person
          example: Utrecht
        countryOfBirth:
          oneOf:
            - $ref: '#/components/schemas/Country'
            - type: 'null'
        nationality:
          oneOf:
            - $ref: '#/components/schemas/Nationality'
            - type: 'null'
        dateOfNationality:
          type:
            - string
            - 'null'
          description: |
            The date of nationality of this person, using the `full-date` format as defined in 
            RFC 3339 (section 5.6).
          format: date
          example: '2003-09-30'
        affiliations:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/personAffiliation'
        email:
          type:
            - string
            - 'null'
          description: The primary email address of this person
          format: email
          maxLength: 256
          example: vandamme.mcw@universiteitvanharderwijk.nl
        secondaryEmail:
          type:
            - string
            - 'null'
          description: The secondary email address of this person
          format: email
          maxLength: 256
          example: poekie@xyz.nl
        telephoneNumber:
          type:
            - string
            - 'null'
          description: The telephone number of this person
          maxLength: 256
          example: +31 123 456 789
        mobileNumber:
          type:
            - string
            - 'null'
          description: The mobile number of this person
          maxLength: 256
          example: +31 612 345 678
        photoSocial:
          type:
            - string
            - 'null'
          description: The url of the informal picture of this person
          format: uri
          maxLength: 2048
          example: https://upload.wikimedia.org/wikipedia/commons/thumb/d/d5/Placeholder_female_superhero_c.png/203px-Placeholder_female_superhero_c.png
        photoOfficial:
          type:
            - string
            - 'null'
          description: The url of the official picture of this person
          format: uri
          maxLength: 2048
          example: https://upload.wikimedia.org/wikipedia/commons/6/66/Johannes_Vermeer_%281632-1675%29_-_The_Girl_With_The_Pearl_Earring_%281665%29.jpg
        gender:
          oneOf:
            - $ref: '#/components/schemas/gender'
            - type: 'null'
        titlePrefix:
          type:
            - string
            - 'null'
          description: A title prefix to be used for this person
          example: drs
        titleSuffix:
          type:
            - string
            - 'null'
          description: A title suffix to be used for this person
          example: BSc
        office:
          type:
            - string
            - 'null'
          description: The name of the office where this person is located
          example: Zernikecomplex
        address:
          oneOf:
            - $ref: '#/components/schemas/Address'
            - type: 'null'
        ICEName:
          type:
            - string
            - 'null'
          description: Full name of In Case of Emergency contact
          maxLength: 256
          example: Janne
        ICEPhoneNumber:
          type:
            - string
            - 'null'
          description: Phone number of In Case of Emergency contact
          maxLength: 256
          example: +31 623 456 789
        ICERelation:
          oneOf:
            - $ref: '#/components/schemas/ICERelationType'
            - type: 'null'
        languageOfChoice:
          type:
            - array
            - 'null'
          description: The language(s) of choice for this person according to RFC4647. For details see the descriptions in the Language schema.
          items:
            $ref: '#/components/schemas/Language'
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
          example:
            - codeType: nationalIdentityNumber
              code: '00000'
        assignedNeeds:
          description: |
            Assigned resources or time based on the needs of a person. 
            They describe which needs the student requires under which conditions e.g. 15% extra time for tests that requires maths skills.
            These needs can later in the flows be mapped to a personalNeed for a specific association.
            Examples of such assignedNeeds: "ExtraTimeOnlyMaths25%", "ExtraTimeOnlyMaths30Min", "ExtraTimeDigitalTests25%"
          type:
            - array
            - 'null'
          items:
            type: object
            properties:
              code:
                description: Human readable value for the code/identifier
                type:
                  - string
                  - 'null'
                example: ExtraTimeOnlyMaths25%
              description:
                type:
                  - array
                  - 'null'
                description: The description of this assignedNeed.
                minItems: 1
                items:
                  $ref: '#/components/schemas/LanguageTypedString'
                example:
                  - language: en-GB
                    value: Extra time for Maths tests shown in a percentile of the overall time of a test
              startDateTime:
                type:
                  - string
                  - 'null'
                description: The moment on which this assigned need starts, RFC3339 (date-time)
                format: date-time
                example: '2025-05-30T20:00:00+01:00'
              endDateTime:
                type:
                  - string
                  - 'null'
                description: The moment on which this assigned need ends, RFC3339 (date-time)
                format: date-time
                example: '2025-07-30T20:00:00+01:00'
          minItems: 0
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    organisationType:
      type: string
      description: |
        The type of this organisation. When using non-root organisation types, make sure that there is always a parent organisation of type root available.

        - root: The top-level organisation, representing the organisation itself
        - institute: A subdivision of the root organisation, typically focused on a broad field of study
        - department: An organisational unit within an organisation or one of the subdivisions of an organisation, focused on a specific discipline
        - faculty: A major academic division within an institution, often overseeing multiple departments
        - branch: A geographically separate location or campus of an organisation
        - academy: A specialised academic unit, often focused on applied or artistic disciplines
        - school: An organisational unit typically used in primary, secondary, or specialised higher education contexts

        This is an extensible enumeration. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - root
        - institute
        - department
        - faculty
        - branch
        - academy
        - school
      example: root
    ProgrammeProperties:
      type: object
      description: A collection of courses that lead to a certifiable learning outcome
      required:
        - programmeType
        - name
        - primaryCode
      properties:
        primaryCode:
          description: The primary human readable identifier for the programme. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
          example:
            codeType: programmeCode
            code: BIO
        programmeType:
          $ref: '#/components/schemas/programmeType'
        name:
          description: The name of this programme
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Biology
        abbreviation:
          type:
            - string
            - 'null'
          description: The abbreviation of this programme
          maxLength: 256
          example: BIO
        description:
          type:
            - array
            - 'null'
          description: The description of this programme
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: The study of life
        teachingLanguages:
          type:
            - array
            - 'null'
          description: The languages in which this programme is given, should be three-letter language codes as specified by ISO 639-2. A student should be reasonably proficient in each language to be able to follow the programme.
          minItems: 1
          items:
            $ref: '#/components/schemas/Language'
        studyLoad:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/StudyLoadDescriptor'
        qualificationAwarded:
          oneOf:
            - $ref: '#/components/schemas/qualificationAwarded'
            - type: 'null'
        qualificationDesignations:
          type: array
          description: Academic field designations that specify the discipline area of the degree (e.g., "of Arts", "of Sciences", "of Engineering"). Multiple designations may apply to interdisciplinary programmes.
          items:
            type: string
            description: The designation suffix indicating the academic field or discipline (e.g., "of Arts" for humanities, "of Sciences" for natural sciences, "of Engineering" for engineering disciplines)
        modeOfStudy:
          oneOf:
            - $ref: '#/components/schemas/modeOfStudy'
            - type: 'null'
        modesOfDelivery:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/modeOfDelivery'
        duration:
          type:
            - string
            - 'null'
          description: The duration of this programme. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339.
          pattern: ^-?P(?:\d+Y)?(?:\d+M)?(?:\d+(?:D|W))?(?:T(?:\d+H)?(?:\d+M)?(?:\d+(?:\.\d+)?S)?)?$
          example: P1DT10H30M
        firstStartDateTime:
          type:
            - string
            - 'null'
          description: The moment when participants can follow this programme for the first time.
          format: date-time
          example: '2025-08-28T08:30:00+01:00'
        levelOfQualification:
          oneOf:
            - $ref: '#/components/schemas/levelOfQualification'
            - type: 'null'
        level:
          oneOf:
            - $ref: '#/components/schemas/level'
            - type: 'null'
        fieldsOfStudy:
          type:
            - string
            - 'null'
          description: |
            Field(s) of study (e.g. ISCED-F) (https://unesdoc.unesco.org/ark:/48223/pf0000228085.locale=en). 
            ISCED-F categorizes the fields of study 2 digits at root level and further subdivision as more digits are added.
            Preferably fieldsOfStudy contains at least 4 digits.
            ISCEDF2013vSOI2021 currently allows for 6 digits max (https://www.cbs.nl/-/media/cbs/onze-diensten/methoden/classificaties/documents/2025/pubsoi2021_ed2425.pdf).
            07 Engineering, manufacturing and construction
            073 Architecture and construction
            0731 Architecture and town planning
            073101 Town planning
          minLength: 2
          maxLength: 6
          example: '0732'
        enrolment:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          description: The extra information that is provided for enrolment
          example:
            - language: en-GB
              value: enrolment through SIS. [The limited implementation of Git Hub Markdown syntax](https://openonderwijsapi.nl/v6.0/#/technical/formatting-text) MAY be used for rich text representation.
        resources:
          type:
            - array
            - 'null'
          description: An overview of the literature and other resources that is used in this course (ECTS-recommended reading and other sources)
          items:
            type: string
          example:
            - book to be announced
            - on-line resource x
        learningOutcomeIds:
          description: |
            The identifiers of the learning outcomes related to this programme.
            When the client does not request expansion of `learningOutcomes`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        learningOutcomes:
          description: |
            The expanded learning outcome objects related to this programme.
            When the client requests expansion of `learningOutcomes`, the full expanded learning outcome objects MUST be returned here instead of only the identifiers.
            If no learning outcomes are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/LearningOutcome'
        assessment:
          type:
            - array
            - 'null'
          description: A description of the way exams for this course are taken (ECTS-assessment method and criteria).
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Exam on campus
        admissionRequirements:
          type:
            - array
            - 'null'
          description: This information may be given at an institutional level and/or at the level of individual programmes. Make sure that it is clear whether the information applies to fee-paying students (national and/or international) or to exchange students.
          example:
            - language: en-GB
              value: Students need to be enrolled at qualifying institutions of higher education that participate in this alliance
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
        qualificationRequirements:
          type:
            - array
            - 'null'
          description: Normally, students will receive a diploma when they have completed the (official) study programme and have obtained the required number of credits. If there are any other specific requirements that students need to have fulfilled, mention them here.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
        formalDocument:
          oneOf:
            - $ref: '#/components/schemas/formalDocument'
            - type: 'null'
        link:
          type:
            - string
            - 'null'
          description: URL of the programme's website
          format: uri
          maxLength: 2048
          example: https://bijvak.nl
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
          example:
            - codeType: crohoCreboCode
              code: '59312'
        addresses:
          type:
            - array
            - 'null'
          description: Addresses for this programme
          items:
            $ref: '#/components/schemas/Address'
        parentId:
          description: |
            The identifier of the parent programme of which the current programme is a child.
            When the client does not request expansion of `parent`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        parent:
          description: |
            The expanded parent programme of which the current programme is a child.
            When the client requests expansion of `parent`, the full expanded programme object MUST be returned here instead of only the identifier.
            If no parent is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Programme'
        childIds:
          description: |
            The identifiers of the programmes which are a part of this programme (e.g. specialisations).
            When the client does not request expansion of `children`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).

            Although `childIds` and `children` (for example `organisationIds` versus `organisations`) may 
            seem unusual, this naming is intentional and follows the singular–plural convention defined 
            by the specification.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        children:
          description: |
            The expanded programme objects which are a part of this programme (e.g. specialisations).
            When the client requests expansion of `children`, the full expanded programme objects MUST be returned here instead of only the identifiers.
            If no children are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Programme'
        coordinatorIds:
          description: |
            The identifiers of the persons responsible for this programme.
            When the client does not request expansion of `coordinators`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        coordinators:
          description: |
            The expanded person objects responsible for this programme.
            When the client requests expansion of `coordinators`, the full expanded person objects MUST be returned here instead of only the identifiers.
            If no coordinators are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Person'
        instructorIds:
          description: |
            The identifiers of the persons teaching or delivering this programme.
            When the client does not request expansion of `instructors`, only these identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        instructors:
          description: |
            The expanded person objects teaching or delivering this programme.
            When the client requests expansion of `instructors`, the full expanded person objects MUST be returned here instead of only the identifiers.
            If no instructors are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Person'
        organisationId:
          description: |
            The identifier of the organisation providing this programme.
            When the client does not request expansion of `organisation`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        organisation:
          description: |
            The expanded organisation object providing this programme.
            When the client requests expansion of `organisation`, the full expanded organisation object MUST be returned here instead of only the identifier.
            If no organisation is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Organisation'
        supplementaryInformation:
          $ref: '#/components/schemas/SupplementaryInformation'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    CourseProperties:
      type: object
      description: An object describing the metadata of a course
      required:
        - name
        - primaryCode
      properties:
        primaryCode:
          description: The primary human readable identifier for this course. This is often the source identifier as defined by the institution.
          $ref: '#/components/schemas/IdentifierEntry'
        name:
          type: array
          description: The name of this course (ECTS-title)
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Academic and Professional Writing
        abbreviation:
          type:
            - string
            - 'null'
          description: The abbreviation or internal code used to identify this course (ECTS-code)
          maxLength: 256
          example: INFOMQNM
        studyLoad:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/StudyLoadDescriptor'
        modesOfDelivery:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/modeOfDelivery'
        duration:
          type:
            - string
            - 'null'
          description: The duration of this course. The duration format is from the ISO 8601 ABNF as given in Appendix A of RFC 3339.
          pattern: ^-?P(?:\d+Y)?(?:\d+M)?(?:\d+(?:D|W))?(?:T(?:\d+H)?(?:\d+M)?(?:\d+(?:\.\d+)?S)?)?$
          example: P1DT10H30M
        firstStartDate:
          type:
            - string
            - 'null'
          description: The date and time when participants can follow this course for the first time.
          format: date-time
          example: '2020-09-28T08:30:00+01:00'
        description:
          type:
            - array
            - 'null'
          description: The description of this course (ECTS-description).
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: As with all empirical sciences, to assure valid outcomes, HCI studies heavily rely on research methods and statistics. This holds for the design of user interfaces, personalized recommender systems, and interaction paradigms for the internet of things. This course prepares you to do so by learning you to collect data, design experiments, and analyse the results. By the end of the course, you will have a detailed understanding of how to select and apply quantitative research methods and analysis to address virtually all HCI challenges. Quantitative research and data analysis will be taught in the context of state-of-the-art HCI challenges. Lectures will be alternated with hands-on learning, including work with predefined datasets (e.g., addressing facial features, cognitive load, and emotion). Additionally, students will set up their own research (e.g., using eye tracking). Data processing and analysis will be executed using R.
        teachingLanguages:
          type:
            - array
            - 'null'
          description: The languages in which this course is given, should be three-letter language codes as specified by RFC 4647. A student should be reasonably proficient in each language to be able to follow the course.
          minItems: 1
          items:
            $ref: '#/components/schemas/Language'
        fieldsOfStudy:
          type:
            - string
            - 'null'
          description: |
            Field(s) of study (e.g. ISCED-F) (https://unesdoc.unesco.org/ark:/48223/pf0000228085.locale=en). 
            ISCED-F categorizes the fields of study 2 digits at root level and further subdivision as more digits are added.
            Preferably fieldsOfStudy contains at least 4 digits.
            ISCEDF2013vSOI2021 currently allows for 6 digits max (https://www.cbs.nl/-/media/cbs/onze-diensten/methoden/classificaties/documents/2025/pubsoi2021_ed2425.pdf).
            07 Engineering, manufacturing and construction
            073 Architecture and construction
            0731 Architecture and town planning
            073101 Town planning
          minLength: 2
          maxLength: 6
          example: '0732'
        learningOutcomeIds:
          description: |
            The identifiers of the learning outcomes related to this course.
            When the client does not request expansion of `learningOutcomes`, only these
            identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        learningOutcomes:
          description: |
            The expanded learning outcome objects related to this course.
            When the client requests expansion of `learningOutcomes`, the full expanded
            learning outcome objects MUST be returned here instead of only the identifiers.
            If no learning outcomes are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/LearningOutcome'
        admissionRequirements:
          type:
            - array
            - 'null'
          description: This information may be given at an institutional level and/or at the level of individual programmes. Make sure that it is clear whether the information applies to fee-paying students (national and/or international) or to exchange students.
          example:
            - language: en-GB
              value: Students need to be enrolled at qualifying institutions of higher education that participate in this alliance
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
        qualificationRequirements:
          type:
            - array
            - 'null'
          description: Normally, students will receive a diploma when they have completed the (official) study programme and have obtained the required number of credits. If there are any other specific requirements that students need to have fulfilled, mention them here.
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
        level:
          oneOf:
            - $ref: '#/components/schemas/level'
            - type: 'null'
        enrolment:
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          description: The extra information that is provided for enrolment
          example:
            - language: en-GB
              value: enrolment through SIS. [The limited implementation of Git Hub Markdown syntax](https://openonderwijsapi.nl/v6.0/#/technical/formatting-text) MAY be used for rich text representation.
        resources:
          type:
            - array
            - 'null'
          description: An overview of the literature and other resources that is used in this course (ECTS-recommended reading and other sources)
          items:
            type: string
          example:
            - book to be announced
            - on-line resource x
        assessment:
          type:
            - array
            - 'null'
          description: A description of the way exams for this course are taken (ECTS-assessment method and criteria).
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Exam on campus
        link:
          type:
            - string
            - 'null'
          description: URL of the course's website
          format: uri
          maxLength: 2048
          example: https://osiris.uu.nl/osiris_student_uuprd/OnderwijsCatalogusZoekCursus.do#submitForm?cursuscode=INFOMQNM
        addresses:
          type:
            - array
            - 'null'
          description: Addresses for this course
          items:
            $ref: '#/components/schemas/Address'
        otherCodes:
          type:
            - array
            - 'null'
          description: An array of additional human readable codes/identifiers for the entity being described.
          items:
            $ref: '#/components/schemas/IdentifierEntry'
        programmeIds:
          description: |
            The identifiers of the programmes of which this course is a part.
            This array is used because a course can belong to multiple programmes,
            for example in alliances.
            When the client does not request expansion of `programmes`, only these
            identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        supplementaryInformation:
          $ref: '#/components/schemas/SupplementaryInformation'
        programmes:
          description: |
            The expanded programme objects of which this course is a part.
            This array is used because a course can belong to multiple programmes,
            for example in alliances.
            When the client requests expansion of `programmes`, the full expanded
            programme objects MUST be returned here instead of only the identifiers.
            If no programmes are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Programme'
        coordinatorIds:
          description: |
            The identifiers of the persons responsible for this course.
            When the client does not request expansion of `coordinators`, only these
            identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        coordinators:
          description: |
            The expanded person objects responsible for this course.
            When the client requests expansion of `coordinators`, the full expanded
            person objects MUST be returned here instead of only the identifiers.
            If no coordinators are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Person'
        instructorIds:
          description: |
            The identifiers of the persons teaching or delivering this course.
            When the client does not request expansion of `instructors`, only these
            identifiers are returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Identifier'
        instructors:
          description: |
            The expanded person objects teaching or delivering this course.
            When the client requests expansion of `instructors`, the full expanded
            person objects MUST be returned here instead of only the identifiers.
            If no instructors are defined, this value is `null`.
          type:
            - array
            - 'null'
          items:
            $ref: '#/components/schemas/Person'
        organisationId:
          description: |
            The identifier of the organisation that manages this course.
            When the client does not request expansion of `organisation`, only this
            identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        organisation:
          description: |
            The expanded organisation object that manages this course.
            When the client requests expansion of `organisation`, the full expanded
            organisation object MUST be returned here instead of only the identifier.
            If no organisation is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Organisation'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    ProgrammeOfferingId:
      type: object
      required:
        - programmeOfferingId
      properties:
        programmeOfferingId:
          type: string
          description: The unique ID of the programme offering, this should be unique across all programme, course, learning, and test component offerings.
          format: uuid
          example: 123e4567-e89b-12d3-a456-134564174000
    LearningComponentOfferingId:
      type: object
      required:
        - learningComponentOfferingId
      properties:
        learningComponentOfferingId:
          type: string
          description: The unique ID of the learning component offering, this should be unique across all programme, course, learning, and test component offerings.
          format: uuid
          example: 123e4567-e89b-12d3-a456-134564174000
    roomType:
      type: string
      description: |
        The type of this room.

        - general_purpose: Multi-purpose space used for general activities or flexible functions.
        - lecture_room: Room primarily used for lectures or large instructional sessions.
        - computer_room: Space equipped with computers for teaching, training or research.
        - laboratory: Room designed for practical experiments, testing or scientific work.
        - office: Workspace for administrative or academic staff.
        - workspace: Shared or individual area for working or studying.
        - exam_location: Designated space for taking written or digital examinations.
        - study_room: Quiet area intended for individual or group study.
        - examination_room: Private space for medical or psychological assessments.
        - conference_room: Room intended for meetings, discussions or presentations.

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - general_purpose
        - lecture_room
        - computer_room
        - laboratory
        - office
        - workspace
        - exam_location
        - study_room
        - examination_room
        - conference_room
      example: exam_location
    learningComponentType:
      type: string
      description: |
        The type of learning component, indicating the format or method of educational delivery.
        One learning component of a certain type can have multiple offerings, one component can refer to a set of componentOfferings.
        e.g. the component lecture can be a set of lectures (group of offerings)
        An example of such a case in natural language: the lecture takes place weekly for 7 weeks
        This implies one learningComponent of type lecture with seven learningComponentOfferings of type lecture. 

        | Code                | Description                                                    |
        |---------------------|----------------------------------------------------------------|
        | `consultation`      | Scheduled meeting for individual or group guidance.            |
        | `excursion`         | Educational trip or site visit.                                |
        | `external`          | Activity outside the home institution (e.g. internship,        |
        |                     | course at a partner institution).                              |
        | `independent_study` | Self-directed learning without scheduled contact hours.        |
        | `learning_community`| Structured collaboration between education, research and       |
        |                     | industry with shared ownership of learning and outcomes;       |
        |                     | distinct from internships and from COIL.                       |
        | `lecture`           | Classroom-based or online lecture given by an instructor.      |
        | `practical`         | Hands-on session focusing on application of concepts.          |
        | `project`           | Structured assignment carried out over a period of time.       |
        | `skills_training`   | Session focused on developing specific practical or            |
        |                     | professional skills.                                           |
        | `tutorial`          | Interactive small-group session to reinforce learning.         |
        | `workshop`          | Intensive session focused on practical skills or knowledge.    |

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - consultation
        - excursion
        - external
        - independent_study
        - learning_community
        - lecture
        - practical
        - project
        - skills_training
        - tutorial
        - workshop
      example: learning_community
    TestComponentOfferingId:
      type: object
      required:
        - testComponentOfferingId
      properties:
        testComponentOfferingId:
          type: string
          description: The unique ID of the test component offering, this should be unique across all programme, course, learning, and test component offerings.
          format: uuid
          example: 123e4567-e89b-12d3-a456-134564174000
    testComponentType:
      type: string
      description: |
        The way the test is conducted. This can be a test on paper, a digital test, a life-skills test, an oral test, or a portfolio assessment.  
        Together with modeOfStudy or assessment, it indicates where the test is taken and how it is conducted:

        - unknown: The type of test is not (yet) known or not specified.
        - test_on_paper: Written examination on paper, typically in a controlled setting.
        - digital_test: Computer-based or online test, conducted via a digital platform.
        - life_skills_test: Practical assessment of real-world competencies and life-skills.
        - oral_test: Spoken examination, typically involving verbal questioning and answering.
        - portfolio_assessment: Evaluation based on a collection of the candidate's work over time.

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - unknown
        - test_on_paper
        - digital_test
        - life_skills_test
        - oral_test
        - portfolio_assessment
      example: test_on_paper
    componentState:
      type: string
      description: |
        The state of this component or offering:
          
        - concept: not yet finalised or published
        - cancelled: withdrawn and no longer available
        - active: currently available and in use
        - inactive: no longer in use, but not cancelled

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - concept
        - cancelled
        - active
        - inactive
      example: active
    documentType:
      type: string
      description: |
        The type of document:

          - additional_document: Used to provide supplementary information
          - assessment_form: A form used to assess a test
          - assessment_model: A formal description of how a test is assessed
          - assignment: A description of what is expected from a student, e.g. to submit a paper
          - attendance_report: A report containing information on a student’s attendance for a course or test
          - handed_in_document: A document submitted by the student
          - instructions: Instructions for the student on how to enrol in a course or take a test
          - plagiarism_report: A report containing information on (potential) plagiarism, e.g. in a submitted document
          - session_report: A report containing information on a session, e.g. an academic session, course, or test session
          - test_made: The completed test, including all answers provided by the student
          - other: Any other type of document not listed above

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - additional_document
        - assessment_form
        - assessment_model
        - assignment
        - attendance_report
        - handed_in_document
        - instructions
        - plagiarism_report
        - session_report
        - test_made
        - other
      example: test_made
    AssociationId:
      type: object
      properties:
        associationId:
          type: string
          description: Unique id of this association
          format: uuid
          example: 123e4567-e89b-12d3-a456-426614174000
      required:
        - associationId
    associationRole:
      type: string
      description: |
        The role of the person associated with the offering:
          
        - student: Enrolled participant in the offering
        - lecturer: Delivers lectures or leads teaching
        - teaching_assistant: Supports the lecturer in teaching activities
        - coordinator: Responsible for organisational or administrative aspects
        - invigilator: Supervises examinations or assessments
        - assessor: Evaluates student performance or work
        - guest: External participant with an atypical role
          
        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - student
        - lecturer
        - teaching_assistant
        - coordinator
        - invigilator
        - assessor
        - guest
      example: student
    associationState:
      type: string
      description: |
        The state of this association:
          
        - pending: A student has requested enrolment, but it has not yet been confirmed, accepted or processed
        - cancelled: The association has been cancelled, for example by the student or the institution
        - denied: The student was denied enrolment, for example because they did not meet the requirements
        - associated: The association has been confirmed, accepted or processed; the student is enrolled
        - queued: The association is in a queue, for example because the course is full
        - finished: The association has ended, for example because the course has ended or the student has completed the course
          
        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - pending
        - cancelled
        - denied
        - associated
        - queued
        - finished
      example: associated
    remoteAssociationState:
      type: string
      description: |
        The state of this association for the organisation performing the request:

        - pending: The association request has been submitted, but not yet processed
        - cancelled: The association request was withdrawn before completion
        - denied: The association request was reviewed, and explicitly rejected
        - associated: The association has been successfully established, and is active
        - queued: The association request is awaiting processing in a queue

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - pending
        - cancelled
        - denied
        - associated
        - queued
      example: associated
    AssociationProperties:
      type: object
      description: A relationship between a person object and an offering
      required:
        - role
        - state
      properties:
        role:
          $ref: '#/components/schemas/associationRole'
        startDateTime:
          type:
            - string
            - 'null'
          format: date-time
          description: The start date and time the person is intended to start participating in the offering. Formatted according to RFC3339 (full-date)
          example: '2025-01-01T08:30:00+01:00'
        expectedEndDateTime:
          type:
            - string
            - 'null'
          format: date-time
          description: The expected end date and time the person is intended to stop participating in the offering. Formatted according to RFC3339 (date-time)
          example: '2025-10-25T08:30:00+01:00'
        actualEndDateTime:
          type:
            - string
            - 'null'
          format: date-time
          description: The actual end date and time the person stopped participating in the offering. Formatted according to RFC3339 (full-date)
          example: '2025-10-23T08:30:00+01:00'
        state:
          $ref: '#/components/schemas/associationState'
        remoteState:
          oneOf:
            - $ref: '#/components/schemas/remoteAssociationState'
            - type: 'null'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    resultState:
      type: string
      description: |
        The state of this result:

        - in_progress: The result is currently being worked on or assessed
        - postponed: The result process has been delayed and will be resumed later
        - completed: The result has been finalised and recorded
        - queued: The result is awaiting processing or evaluation

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - in_progress
        - postponed
        - completed
        - queued
      example: completed
    passState:
      type: string
      description: |
        The state of this result:

        - unknown: The result has not been determined, recorded, or is not yet available
        - passed: The individual has met the required criteria to pass
        - failed: The individual did not meet the required criteria to pass

        This is an extensible enumeration. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - unknown
        - passed
        - failed
      example: passed
    Document:
      type: object
      required:
        - documentId
        - documentType
        - documentName
      properties:
        documentId:
          type: string
          description: The unique identifier of the document
          example: 12345678-1234-1234-1234-123456789012
        documentType:
          $ref: '#/components/schemas/documentType'
        documentName:
          type: string
          description: The name of the document
          example: paper_test_1234333.pdf
    Result:
      type: object
      description: A result as part of an association or attempt
      required:
        - state
        - resultDateTime
      properties:
        state:
          $ref: '#/components/schemas/resultState'
        pass:
          oneOf:
            - $ref: '#/components/schemas/passState'
            - type: 'null'
        comment:
          type:
            - string
            - 'null'
          description: The comment on this result
          example: Strong performance overall, only minor calculation errors in section 3.
        score:
          type:
            - string
            - 'null'
          description: The score of this programme/course/component association (based on resultValueType in offering)
          example: '9'
        rawScore:
          type:
            - integer
            - 'null'
          description: |
            The number of points scored by a person (on the test or assessment) from which the result could be calculated. 
            The raw score provides additional insight in the achievement of the person. 
            The raw score also needs the value of maxRawScore to provide necessary context.
          example: 72
        maxRawScore:
          type:
            - integer
            - 'null'
          description: |
            The maximum number of points a person could achieve on the test or assessment form.
          example: 80
        final:
          type:
            - boolean
            - 'null'
          default: false
          description: |
            final: indicates that the result has been finalised by the exam committee. 
            This can be done in any step of the test taking and assessment cycle. 
          example: true
        assessorId:
          description: |
            The identifier of the assessor responsible for evaluating the result.
            When the client does not request expansion of `assessor`, only this identifier is returned.
            This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
          $ref: '#/components/schemas/Identifier'
        assessor:
          description: |
            The expanded assessor (person) responsible for evaluating the result.
            When the client requests expansion of `assessor`, the full person object MUST be returned here instead of only the identifier.
            If no assessor is defined, this value is `null`.
          type:
            - object
            - 'null'
          allOf:
            - $ref: '#/components/schemas/Person'
        resultDateTime:
          type: string
          description: The date this result has been published, RFC3339 (full-date)
          format: date-time
          example: '2025-11-28T08:30:00+01:00'
        documents:
          type:
            - array
            - 'null'
          description: |
            Documents that are related to the result of the test component offering association. E.g. assessment form, assessment model, etc.
          items:
            $ref: '#/components/schemas/Document'
        consumer:
          oneOf:
            - $ref: '#/components/schemas/Consumer'
            - type: 'null'
        ext:
          oneOf:
            - $ref: '#/components/schemas/Ext'
            - type: 'null'
    CourseOfferingAssociationResult:
      allOf:
        - $ref: '#/components/schemas/Result'
        - type: object
          required:
            - studyLoad
          properties:
            studyLoad:
              $ref: '#/components/schemas/StudyLoadDescriptor'
    CourseOfferingAssociationExternalMe:
      allOf:
        - $ref: '#/components/schemas/AssociationId'
        - $ref: '#/components/schemas/AssociationProperties'
        - type: object
          anyOf:
            - required:
                - courseOfferingId
            - title: With expanded course offering
              required:
                - courseOffering
          properties:
            studyLoad:
              description: |
                Only required when the studyload for the individual student/enrolment is different 
                from the studyload of the course offering.
              oneOf:
                - $ref: '#/components/schemas/StudyLoadDescriptor'
                - type: 'null'
            result:
              oneOf:
                - $ref: '#/components/schemas/CourseOfferingAssociationResult'
                - type: 'null'
            courseOfferingId:
              description: |
                The identifier of the courseOffering referenced here.
                When the client or server does not expand `offering`, only this
                identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            courseOffering:
              description: |
                The expanded courseOffering object referenced here.
                When the client or server expands `offering`, the full expanded
                courseOffering object MUST be returned here instead of only the
                identifier.
                If no offering is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/CourseOffering'
    PostResponse:
      type: object
      description: A system message as a response to a POST message
      required:
        - message
      properties:
        message:
          description: information displayed to user
          type: array
          minItems: 1
          items:
            $ref: '#/components/schemas/LanguageTypedString'
          example:
            - language: en-GB
              value: Your enrolment was partly successful, you have been placed on the waiting list
        redirect:
          description: URL where additional information can be found e.g. by use of deep link
          type:
            - string
            - 'null'
          format: uri
          maxLength: 2048
          example: https://university.example.org/
    groupType:
      type: string
      description: |
        The type of this group:

        - class: A group of students jointly scheduled for, assigned to, or engaged in educational activities
        - team: A group composed of members of a team, which may consist of students, staff, or a mix of both
        - group: A group of students jointly scheduled for, assigned to, or engaged in educational activities in a context not covered by a class

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - class
        - team
        - group
      example: class
    GroupId:
      type: object
      required:
        - groupId
      properties:
        groupId:
          type: string
          description: The unique ID of the group.
          format: uuid
          example: 123e4567-e89b-12d3-a456-134564174000
    courseOfferingId:
      type: string
      description: The unique ID of the course offering, this should be unique across all programme, course, learning, and test component offerings.
      format: uuid
      example: 123e4567-e89b-12d3-a456-134564174000
    programmeOfferingId:
      type: string
      description: The unique ID of the programme offering, this should be unique across all programme, course, learning, and test component offerings.
      format: uuid
      example: 123e4567-e89b-12d3-a456-134564174000
    learningComponentOfferingId:
      type: string
      description: The unique ID of the learning component offering, this should be unique across all programme, course, learning, and test component offerings.
      format: uuid
      example: 123e4567-e89b-12d3-a456-134564174000
    testComponentOfferingId:
      type: string
      description: The unique ID of the test component offering, this should be unique across all programme, course, learning, and test component offerings.
      format: uuid
      example: 123e4567-e89b-12d3-a456-134564174000
    TimelineOverrideCourse:
      type: object
      required:
        - validFrom
        - course
      description: A timeline override of the course.
      properties:
        validFrom:
          type: string
          description: The day on which this timelineOverride starts (inclusive), RFC3339 (date)
          format: date-time
          example: '2025-09-01T08:30:00+01:00'
        validTo:
          type:
            - string
            - 'null'
          description: The day on which this timelineOverride ends (exclusive), RFC3339 (date)
          format: date-time
          example: '2025-11-30T08:30:00+01:00'
        course:
          $ref: '#/components/schemas/CourseProperties'
    CourseExpanded:
      allOf:
        - $ref: '#/components/schemas/Course'
        - type: object
          description: These properties are only present when explicitly included
          properties:
            timelineOverrides:
              description: Timeline overrides allow an implementation to provide versions of entities that will be valid in the future or have been in the past.
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/TimelineOverrideCourse'
    membershipState:
      type: string
      description: |
        The state of this membership:

        - cancelled: The membership has been formally terminated and is no longer valid
        - active: The membership is currently valid and in effect

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - cancelled
        - active
      example: active
    membershipRole:
      type: string
      description: |
        The role of this person in the context of this membership:

        - student: Enrolled participant in the offering
        - lecturer: Delivers lectures or leads teaching
        - teaching_assistant: Supports the lecturer in teaching activities
        - coordinator: Responsible for organisational or administrative aspects
        - invigilator: Supervises examinations or assessments
        - assessor: Evaluates student performance or work
        - guest: External participant with an atypical role

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - student
        - lecturer
        - teaching_assistant
        - coordinator
        - invigilator
        - assessor
        - guest
      example: student
    LearningComponentOfferingAssociationResult:
      allOf:
        - $ref: '#/components/schemas/Result'
        - type: object
          properties:
            weight:
              type: integer
              description: The weight to 100 as total for this offering in the course
              format: int32
              minimum: 0
              maximum: 100
              example: 100
    associationAttendance:
      type: string
      description: |
        The attendance status of an individual's association with an offering:
        - unknown: attendance status is unknown or unrecorded
        - not_started: attendance has not yet begun
        - unfinished: attendance has begun but not completed
        - present: individual attended as expected
        - absent: individual did not attend

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - unknown
        - not_started
        - unfinished
        - present
        - absent
      example: present
    ProgrammeOfferingAssociationResult:
      allOf:
        - $ref: '#/components/schemas/Result'
        - type: object
          required:
            - studyLoad
          properties:
            studyLoad:
              $ref: '#/components/schemas/StudyLoadDescriptor'
    ProgrammeOfferingAssociationExternalMe:
      allOf:
        - $ref: '#/components/schemas/AssociationId'
        - $ref: '#/components/schemas/AssociationProperties'
        - type: object
          anyOf:
            - required:
                - programmeOfferingId
            - title: With expanded programme offering
              required:
                - programmeOffering
          properties:
            result:
              oneOf:
                - $ref: '#/components/schemas/ProgrammeOfferingAssociationResult'
                - type: 'null'
            programmeOfferingId:
              description: |
                The identifier of the `programmeOffering` referenced here.
                When the client does not request expansion of `offering`, only this identifier is returned.
                This field is [`expandable`](https://openonderwijsapi.nl/v6.0/#/technical/expanding-responses).
              $ref: '#/components/schemas/Identifier'
            programmeOffering:
              description: |
                The expanded programmeOffering object referenced here.
                When the client requests expansion of `offering`, the full expanded programmeOffering object MUST be returned here instead of only the identifier.
                If no offering is defined, this value is `null`.
              type:
                - object
                - 'null'
              allOf:
                - $ref: '#/components/schemas/ProgrammeOffering'
    personalNeed:
      type: string
      description: |
        The personal needs required for this component by this specific candidate.

        This list is a selection from the IMS Global Personal Needs and Preferences specification.
        For the full reference, see:  
        https://www.imsglobal.org/sites/default/files/spec/afa/3p0/information_model/imsafa3p0pnp_v1p0_InfoModel.html

        - extra_time: Additional time allocated for completing the component beyond standard timing
        - spoken: Spoken output support (e.g. text-to-speech)
        - spell_checker_on_screen: On-screen spell checking tool enabled during writing tasks

        This is an extensible enumeration. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - extra_time
        - spoken
        - spell_checker_on_screen
      example: extra_time
    TestComponentOfferingAssociationResult:
      allOf:
        - $ref: '#/components/schemas/Result'
        - type: object
          properties:
            weight:
              type: integer
              description: The weight to 100 as total for this offering in the course
              format: int32
              minimum: 0
              maximum: 100
              example: 100
    attemptState:
      type: string
      description: |
        Status of the fulfilment of the attempt. 
        The status typically progresses from pending to associated and then to finished. 
        - pending: A student is associated to the offering, but has not yet been allocated a specific attempt.
        - cancelled: The attempt has been cancelled, for example by the student or the institution
        - associated: The attempt has been confirmed/accepted/processed, the student is enrolled for a specific test moment
        - finished: The attempt has ended, for example because the student has ended the test or the student has completed the test, or the deadline for handing in / finishing the test has expired.
      x-ooapi-extensible-enum:
        - pending
        - cancelled
        - associated
        - finished
      example: associated
    attendance:
      type: string
      description: |
        The attendance status of an individual's association with an offering:
        - unknown: attendance status is unknown or unrecorded
        - not_started: attendance has not yet begun
        - unfinished: attendance has begun but not completed
        - present: individual attended as expected
        - absent: individual did not attend

        This is an *extensible enumeration*. Use the prefix `x-` for custom values.
      x-ooapi-extensible-enum:
        - unknown
        - not_started
        - unfinished
        - present
        - absent
      example: present
    TimelineOverrideProgramme:
      type: object
      description: A time-line override of the programme.
      required:
        - validFrom
        - programme
      properties:
        validFrom:
          type: string
          description: The day on which this timelineOverride starts (inclusive), RFC3339 (date)
          format: date-time
          example: '2025-09-01T08:30:00+01:00'
        validTo:
          type:
            - string
            - 'null'
          description: The day on which this timelineOverride ends (exclusive), RFC3339 (date)
          format: date-time
          example: '2025-11-30T08:30:00+01:00'
        programme:
          $ref: '#/components/schemas/ProgrammeProperties'
    ProgrammeExpanded:
      allOf:
        - $ref: '#/components/schemas/Programme'
        - type: object
          description: These properties are only present when explicitly included. This allows for creating and displaying structures of programmes
          properties:
            timelineOverrides:
              description: Timeline overrides allow an implementation to provide versions of entities that will be valid in the future or have been in the past.
              type:
                - array
                - 'null'
              items:
                $ref: '#/components/schemas/TimelineOverrideProgramme'
    Url:
      type: string
      description: Url containing a web address.
      format: uri
      maxLength: 2048
      example: https://www.universiteitvanharderwijk.nl
    TestComponentOfferingAssociationAttemptFull:
      allOf:
        - $ref: '#/components/schemas/TestComponentOfferingAssociationAttempt'
        - type: object
          properties:
            courseOfferingAssociationId:
              type:
                - string
                - 'null'
              description: |
                The unique identifier of the student’s enrolment in a course offering to which the 
                current association relates.
              format: uuid
              example: 123e4567-e89b-12d3-a456-426614174000
            testComponentOfferingAssociationId:
              type:
                - string
                - 'null'
              description: |
                The associationId under which this attempt was made.
              format: uuid
              example: 123e4567-e89b-12d3-a456-426614174000
  responses:
    ErrorBadRequest:
      description: Bad request
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://api.example.org/problems/invalid-parameter
            title: Invalid request parameters
            status: 400
            detail: 'The query parameter ''mode'' must be one of: full, basic.'
            instance: https://api.example.org/courses?mode=invalid
    ErrorUnauthorized:
      description: Unauthorized
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://api.example.org/problems/unauthorized
            title: Unauthorized
            status: 401
            detail: Authentication credentials were missing or invalid.
            instance: https://api.example.org/student/12345
    ErrorForbidden:
      description: Forbidden
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://api.example.org/problems/forbidden
            title: Forbidden
            status: 403
            detail: You do not have permission to access this resource.
            instance: https://api.example.org/admin/enrolments
    ErrorNotFound:
      description: |
        Not Found.  

        Returned only when a specific resource identified by its identifier
        cannot be located. This applies to instance endpoints where a single,
        uniquely-addressable object is expected.  

        Collection endpoints should not return a 404. If no items match the request,
        they must return an empty array. A 404 may still occur if the collection
        endpoint itself does not exist or is not accessible.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          examples:
            instanceNotFound:
              summary: 'Instance endpoint: resource not found'
              value:
                type: https://api.example.org/problems/not-found
                title: Resource not found
                status: 404
                detail: The course with id 'abc123' could not be found.
                instance: https://api.example.org/courses/abc123
            collectionEndpointNotFound:
              summary: Collection endpoint unavailable
              value:
                type: https://api.example.org/problems/not-found
                title: Collection endpoint not found
                status: 404
                detail: The collection endpoint '/course-offerings' does not exist or is not accessible.
                instance: https://api.example.org/course-offerings
    ErrorMethodNotAllowed:
      description: Method not allowed
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://api.example.org/problems/method-not-allowed
            title: Method not allowed
            status: 405
            detail: The method POST is not supported for this endpoint.
            instance: https://api.example.org/courses/abc123
    ErrorNotAcceptable:
      description: |
        Not Acceptable.

        Returned when the server cannot produce a representation in the
        requested OOAPI or consumer version. The server may serve the
        requested version or any lower compatible minor version.

        If neither the requested version nor a lower minor version is
        available, a 406 response is returned to indicate that no acceptable
        representation can be produced.

        This behaviour slightly deviates from strict HTTP semantics. Although
        no HTTP Accept header is used, the server performs an internal
        Accept-like version check after the HTTP layer, and returns 406 to
        signal that the requested representation cannot be provided.

        This approach improves clarity, implementation consistency and
        debugging, because the requested and supported versions are explicit
        in both the request and the 406 response, avoiding ambiguity caused
        by full HTTP content negotiation or Accept-based parsing.

        It also improves logging. Servers can log the requested and supported
        versions at the point of mismatch, allowing operators to detect
        outdated consumers, configuration issues or unexpected version drift.
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/ProblemVersionNotAcceptable'
          examples:
            unsupportedOoapiVersion:
              summary: Requested OOAPI version is not supported
              description: |
                Example where the client requests OOAPI version 5.0 and the server
                cannot serve that version or a lower compatible minor version.
              value:
                type: https://api.example.org/problems/version-not-acceptable
                title: Version not acceptable
                status: 406
                detail: The requested OOAPI version '5.0' cannot be served.
                requestedVersion: '5.0'
                supportedVersions:
                  - '6.1'
                  - '6.0'
                instance: https://api.example.org/courses
            unsupportedConsumerVersion:
              summary: Requested consumer version is not supported
              description: |
                Example where the client requests consumer version 2.0 which is not
                supported by the server and no lower compatible consumer version is
                available.
              value:
                type: https://api.example.org/problems/version-not-acceptable
                title: Consumer version not acceptable
                status: 406
                detail: The consumer version '2.0' is not supported.
                requestedVersion: '2.0'
                supportedVersions:
                  - '1.0'
                  - '0.94'
                instance: https://api.example.org/enrolments
    ErrorTooManyRequests:
      description: Too many requests
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://api.example.org/problems/too-many-requests
            title: Too many requests
            status: 429
            detail: You have exceeded the rate limit of 100 requests per minute.
            instance: https://api.example.org/courses
    ErrorInternalServerError:
      description: Internal Server Error
      content:
        application/problem+json:
          schema:
            $ref: '#/components/schemas/Problem'
          example:
            type: https://api.example.org/problems/internal-server-error
            title: Internal server error
            status: 500
            detail: An unexpected error occurred while processing your request.
            instance: https://api.example.org/enrolments/submit
  parameters:
    primaryCode:
      name: primaryCode
      in: query
      description: The primaryCode of the requested item. This is often the source identifier as defined by the institution.
      required: false
      schema:
        type: string
    pageSize:
      name: pageSize
      in: query
      description: The number of items per page
      required: false
      schema:
        type: integer
        format: int32
        default: 10
        enum:
          - 10
          - 20
          - 50
          - 100
          - 250
    pageNumber:
      name: pageNumber
      in: query
      description: The page number to get. Page numbers start at 1.
      required: false
      schema:
        type: integer
        format: int32
        example: 1
        minimum: 1
    consumer:
      name: consumer
      in: query
      description: Request entities intended for a specific consumer. The `consumer` profile allows for adding additional data, or specific rules concerning the presentation of the data. A consumer can be selected based on the key of the consumer profile. An implementation of the OOAPI SHOULD always return the consumer information inside the consumer property of the object(s) that are requested. Further information regarding the use of consumers can be found in the [documentation](https://openonderwijsapi.nl/v6.0/#/technical/consumers-and-profiles/)
      required: false
      schema:
        type: string
    filterQuery:
      name: filter_query
      in: query
      required: false
      style: deepObject
      explode: true
      description: |
        Filter object serialised as `filter_query[field][operation]=value`.
        Multiple top-level fields are combined with AND. CSV is accepted where noted.

        Inspired by Storyblok (https://www.storyblok.com/docs/api/content-delivery/v2/filter-queries)

        Wildcards:
        - Prefer using only the asterisk `*` as a wildcard for partial matches (e.g., like and not_like).

        Implementation note:
        - The availability and behaviour of this query functionality are entirely determined by the organisation hosting
          the API implementation. It is not mandatory for implementers to support this functionality, and it cannot be enforced 
          upon organisations that provide or consume OOAPI endpoints.
        - It is up to each implementer to decide whether to support this feature. It is **not** a requirement of the OOAPI 
          standard itself.
        - Consumers or working groups that wish to apply specific filtering mechanisms are encouraged to do so using 
          this approach for the sake of consistency across implementations.

        Examples:  
        - **Filter course offerings by programme, delivery, language and start date**  
          `filter_query[programme.code][in]=B-IT-2025&filter_query[organisation.code][in]=RuG&filter_query[mode_of_delivery][in]=on_campus,hybrid&filter_query[language_of_instruction][in]=en-GB&filter_query[start_date][gt_date]=2025-09-01T00:00:00Z`  
          
        - **Only offerings with email contact present**  
          `filter_query[contacts.email][is]=not_empty`  
      schema:
        type: object
        additionalProperties:
          type: object
          properties:
            is:
              $ref: '#/components/schemas/filterPresence'
            in:
              type: string
              description: Exact match; multiple values allowed as CSV.
              example: RuG
            not_in:
              type: string
              description: Negated inclusion; multiple values as CSV.
              example: UvA,VU
            like:
              type: string
              description: |
                Partial match using wildcards. Prefer `*` as the wildcard.
              example: '*Amsterdam*'
            not_like:
              type: string
              description: |
                Negated partial match using wildcards. Prefer `*` as the wildcard.
              example: '*deprecated*'
            any_in_array:
              type: string
              description: Match if any of the CSV values occur.
              example: evening,block_week
            all_in_array:
              type: string
              description: Match if all CSV values occur.
              example: evening,block_week
            gt_int:
              type: integer
              description: Greater than (integer).
              example: 5
            lt_int:
              type: integer
              description: Less than (integer).
              example: 30
            gt_float:
              type: number
              description: Greater than (float).
              example: 5.5
            lt_float:
              type: number
              description: Less than (float).
              example: 12
            gt_date:
              type: string
              format: date-time
              description: ISO 8601 date-time.
              example: '2025-09-01T00:00:00Z'
            lt_date:
              type: string
              format: date-time
              description: ISO 8601 date-time.
              example: '2025-12-31T23:59:59Z'
    filterQueryOr:
      name: filter_query[__or][]
      in: query
      required: false
      style: deepObject
      explode: true
      description: |
        OR blocks. Provide an array of single-field filter objects, each combined with OR.
        Serialises as `filter_query[__or][][field][operation]=value`.

        Inspired by Storyblok (https://www.storyblok.com/docs/api/content-delivery/v2/filter-queries)

        Wildcards:
        - Prefer using only the asterisk `*` as a wildcard for partial matches (e.g., like).

        Implementation note:
        - The availability and behaviour of this query functionality are entirely determined by the organisation hosting
          the API implementation. It is not mandatory for implementers to support this functionality, and it cannot be enforced 
          upon organisations that provide or consume OOAPI endpoints.
        - It is up to each implementer to decide whether to support this feature. It is **not** a requirement of the OOAPI 
          standard itself.
        - Consumers or working groups that wish to apply specific filtering mechanisms are encouraged to do so using 
          this approach for the sake of consistency across implementations.

        Examples:  
          - **Provider is Org A or Org B, OR campus city contains “Utrecht”**  
            `?filter_query[__or][][organisation.id][in]=org-uu,org-hku&filter_query[__or][][campus.city][like]=*Utrecht*`  
            
          - **Start date after 1 Sept 2025 OR has evening/block_week tag**  
            `?filter_query[__or][][start_date][gt_date]=2025-09-01T00:00:00Z&filter_query[__or][][tags][any_in_array]=evening,block_week`  
      schema:
        type: array
        items:
          type: object
          additionalProperties:
            type: object
            properties:
              in:
                type: string
                description: Exact match; multiple values allowed as CSV.
                example: org-uu,org-hku
              like:
                type: string
                description: |
                  Partial match using wildcards. Prefer `*` as the wildcard.
                example: '*Utrecht*'
              any_in_array:
                type: string
                description: Match if any of the CSV values occur.
                example: evening,block_week
              gt_date:
                type: string
                format: date-time
                description: ISO 8601 / RFC 3339 date-time.
                example: '2025-09-01T00:00:00Z'
              lt_date:
                type: string
                format: date-time
                description: ISO 8601 / RFC 3339 date-time.
                example: '2025-12-31T23:59:59Z'
    fields:
      name: fields
      in: query
      required: false
      style: form
      explode: false
      description: |
        Allows clients to indicate which fields should be included in the response.  
        This parameter supports the principle of data minimisation and helps to optimise 
        data usage and performance by reducing unnecessary data transmission.

        The `fields` parameter uses *nested field selection syntax* with parentheses for subfields, 
        for example: `programme(code)` or `campus(city)`.  
        Multiple fields can be grouped within parentheses, for example:  
        `fields=(id,title,ectsCredits,programme(code),campus(city))`.

        When omitted, the server returns all fields the client has access to.  
        Unknown field names SHOULD be ignored.  
        The server MUST always include *mandatory fields* (e.g., identifiers such as `id`) 
        that are required for a valid or minimal response, even if not explicitly requested.

        *Important:* This is a **request hint**, not a **security feature**.  
        The server MAY disregard the request for a restricted set of fields, and the final response 
        structure MAY depend on server logic and the client’s access rights.


        If a client requests unauthorised fields, these MUST be silently omitted or redacted.
      schema:
        type: string
        example: (id,title,ectsCredits,programme(code),campus(city))
      examples:
        minimal:
          summary: Return a minimal fieldset for course offerings
          value: (id,title,ectsCredits,languageOfInstruction)
        nested:
          summary: Include nested programme code and campus city
          value: (id,title,programme(code),campus(city))
        combined:
          summary: Example using multiple nested fields
          value: (id,title,ectsCredits,programme(code,name),campus(city,country))
    search:
      name: q
      in: query
      description: Filter by items having a name, abbreviation or description containing the given search term (exact partial match, case insensitive)
      required: false
      schema:
        type: string
    teachingLanguage:
      name: teachingLanguage
      in: query
      description: Filter by teachingLanguage, which is a string describing the main teaching language, should be at least a two-letter language code as specified by ISO 6467.
      required: false
      schema:
        type: string
        pattern: ^([a-z]{2,3})(-([A-Z]{2}|[0-9]{3}))?(-([a-z]{4}))?(-([a-z]{2}|[0-9]{3}))*(-[a-z0-9]{2,8})*(-x(-[a-z0-9]{1,8})+)?$
        minLength: 2
      example: nl
    offeringState:
      name: state
      in: query
      description: Filter by an Offering's `state`.
      required: false
      schema:
        $ref: '#/components/schemas/offeringState'
    returnTimelineOverrides:
      name: returnTimelineOverrides
      in: query
      description: Controls whether the attribute `timelineOverrides` is returned or not. The default is `false`, so this has to explicitly set to `true` if a client needs the timeline overrides.
      required: false
      schema:
        type: boolean
        default: false
    personSearch:
      name: q
      in: query
      description: |
        Filter by persons having a given name, surname prefix, surname, display name, initials, email
        or secondary email containing the given search term (exact partial match, case insensitive)
      required: false
      schema:
        type: string
x-tagGroups:
  - name: Requests and responses
    tags:
      - security
      - service metadata
      - academic sessions
      - associations
      - buildings
      - courses
      - course offerings
      - course offering associations
      - components
      - documents
      - groups
      - learning components
      - learning component offerings
      - learning component offering associations
      - learning outcomes
      - news
      - organisations
      - persons
      - programmes
      - programme offerings
      - programme offering associations
      - rooms
      - test components
      - test component offerings
      - test component offering associations
      - test component offering association attempts
  - name: Models
    tags:
      - data_model
      - service_model
      - learning_outcome_model
      - academic_session_model
      - building_model
      - course_model
      - course_offering_model
      - course_offering_association_model
      - document_model
      - learning_component_model
      - learning_component_offering_model
      - learning_component_offering_association_model
      - test_component_model
      - test_component_offering_model
      - test_component_offering_association_model
      - test_component_offering_association_attempt_model
      - group_model
      - membership_model
      - organisation_model
      - person_model
      - programme_model
      - programme_offering_model
      - programme_offering_association_model
      - room_model
